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^

...しかし、これもまたRatio.Tをインポートして、私の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/)。 –

+1

@leftaroundについて私は彼の原因を幾分感じていますが、確かにそれをうまく言語から[良い](http://doc.rust-lang.org/std /error/trait.Error.html)[module](https://doc.rust-lang.org/std/fmt/struct.Error.html)[システム](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

ローカルシノニム '(%)=(Ratio。:%)' – luqui

+0

@luquiを定義することもできます。 'PatternSynonyms'拡張を使用して、データコンストラクタのエイリアスを行う方法に慣れていません。 –

+3

@ExpHP'パターンx:%y = x Ratio.:% y'。 –

関連する問題