2016-09-10 3 views
8

numeric-prelude 모든 데이터 형식의 이름은 T이고 모든 형식 클래스의 이름은 C입니다. 의 ... 일관성을 위해, 내가 함께 플레이를 해 가정 :형식을 가져 오지 않고 데이터 생성자를 가져옵니다.

{-# LANGUAGE NoImplicitPrelude #-} 
module Number.SqrtRatio (T(..), ratioPart) where 

import qualified Number.Ratio as Ratio 
import Number.Ratio ((:%)) 

import qualified Algebra.Ring as Ring 
import NumericPrelude.Base 

-- | A number whose square is rational, canonicalized as a rational 
-- times the square root of a squarefree integer. 
data T x = T { 
    numerator :: !x, 
    denominator :: !x, 
    rootNum :: !x 
    } deriving (Eq, Show) 

ratioPart :: T x -> Ratio.T x 
ratioPart (T n d _) = n :% d 

fromRatio :: (Ring.C x) => Ratio.T x -> T x 
fromRatio (n :% d) = T n d Ring.one 

ghc이 인상되지 않습니다 :

Number/SqrtRatio.hs:5:22: 
    In module ‘Number.Ratio’: 
     ‘(:%)’ is a data constructor of ‘T’ 
    To import it use 
     ‘import’ Number.Ratio(T((:%))) 
    or 
     ‘import’ Number.Ratio(T(..)) 

물론이지 친구, 나는 준수 할 수

{-# LANGUAGE NoImplicitPrelude #-} 
module Number.SqrtRatio (T, ratioPart) where 

import qualified Number.Ratio as Ratio 
import Number.Ratio (T((:%))) 
--  newly added^

...하지만이 또한 내 T과 충돌하는 Ratio.T을 가져옵니다.

ratioPart :: T x -> Ratio.T x 
{-   ^-- Ambiguous occurrence ‘T’ 
    It could refer to either ‘Number.SqrtRatio.T’, 
          defined at Number/SqrtRatio.hs:11:1 
          or ‘Number.Ratio.T’, 
          imported from ‘Number.Ratio’ at Number/SqrtRatio.hs:5:22-28 
-} 

좋아, 그래서 방법에 대한 import Number.Ratio (T((:%))) hiding T?

Number/SqrtRatio.hs:5:31: parse error on input ‘hiding’ 

저는 약간의 상실감이 있습니다. :/

+2

아, 네. 헤닝이이 명명 규칙을 고집하지 않았 으면합니다. 누군가 농담으로 말했듯이 : _ 그는 자신의 모든 데이터 유형을 자신의 이름 뒤에 붙여주는 것을 좋아합니다. (** T ** hielemann) ... 나는 자신의 선택을 존중하고 신뢰하지 않는다고 말하는 것이 아닙니다. 모듈을 기본 명명 계층 구조로 사용합니다. 그러나 아무도이 작업을 수행하지 않으므로이 문제를 진정으로 해결할 수는 없습니다. 그리고 어떤 경우에는 당신이 여기있는 것과 같이 실제로는 잘 작동하지 않습니다. 문서의 가독성에 대해서는 언급하지 않습니다. 정체 : 'T'라고 전화하지 마라. – leftaroundabout

+1

모든 Haddock 페이지에서 제일 먼저 클릭해야하는 것은 [소스 링크]입니다. (http://hackage.haskell.org/package/numeric-prelude-0.4.2/docs/src/ Number-Ratio.html) –

+1

@leftaroundabout 나는 [좋은] 언어 (http://doc.rust-lang.org/std)가있는 언어로 이것을 멋지게 추출 할 수 있기 때문에 그의 생각으로는 다소 느낍니다. /error/trait.Error.html) [module] (https://doc.rust-lang.org/std/fmt/struct.Error.html) [system] (https://doc.rust-lang.org) /std/io/struct.Error.html).그러나 그런 것은 하스켈이 아닙니다. –

답변

8

이 작업을 수행 할 수있는 적절한 방법 거기 밝혀 :

나는 분명히 그래서 그냥 pattern 키워드를 사용하려면, 실제로 패턴 동의어를 정의하지 -XPatternSynonyms 확장자를 사용했습니다
{-# LANGUAGE NoImplicitPrelude, PatternSynonyms #-} 
module Number.SqrtRatio (T(..), ratioPart) where 

import qualified Number.Ratio as Ratio 
import Number.Ratio (pattern (:%)) 

값 생성자:% 만 가져 오려고합니다.

+0

인상적인 발견! 이 기능에서 찾을 수있는 모든 문서는 해당 생성자가 원래 모듈에서'pattern :'을 사용하여 선언 된 경우에만 적용됩니다 ('(: %)'는 그렇지 않습니다). 이것은 수출 된 생성자가 동의어로 투명하게 대체 될 수 있도록하기 위해 작동한다는 것이 합리적입니다. –

3

나의 현재 솔루션은 게시하기 전에 순간을 발견 :

  • (:%)을 가져 오려는에 포기.
  • 정규화 된 가져 오기를 유지하십시오.
  • 어디서나 (패턴 및 표현식) :% ~ Ratio.:%으로 변경하십시오.

결과 :

{-# LANGUAGE NoImplicitPrelude #-} 
module Number.SqrtRatio (T(..), ratioPart) where 

import qualified Number.Ratio as Ratio 

import qualified Algebra.Ring as Ring 
import NumericPrelude.Base 

-- | A number whose square is rational, canonicalized as a rational 
-- times the square root of a squarefree integer. 
data T x = T { 
    numerator :: !x, 
    denominator :: !x, 
    rootNum :: !x 
    } deriving (Eq, Show) 

ratioPart :: T x -> Ratio.T x 
ratioPart (T n d _) = n Ratio.:% d 

fromRatio :: (Ring.C x) => Ratio.T x -> T x 
fromRatio (n Ratio.:% d) = T n d Ring.one 

미운.

+1

표현식으로도 작동 할 수있는 로컬 동의어'(%) = (비율 : %)' – luqui

+0

@luqui를 정의 할 수 있지만 패턴은 어떨까요? 'PatternSynonyms' 확장을 사용하여 데이터 생성자의 별칭을 익히는 데 익숙하지 않습니다. –

+3

@ExpHP'패턴 x : % y = x Ratio.:% y'. –

관련 문제