あなたがそこに書かれたものはクラス宣言、ないインスタンスのようにたくさん見えます。おそらく、あなたはこれを意味しましたか?
class Printable n where
print :: n -> IO()
read :: String -> n
それはあなたがクラスを超える量子化するしている型変数だからn
は、小文字にする必要があることに注意。あなたが実際にインスタンスを定義したい場合、あなたはよく、N
でn
をインスタンス化:
instance Printable N where
print n = ...
read str = ...
をこの時点で型(クラス定義から)がすべて固定されている署名と何がする必要があります書き込みは、これらの関数の実際のバインディングなので、ではなく、=
でなければなりません。
質問:あなたはどうして自分のクラスを必要としますか?すでにプレリュードに入っている標準機能print
とread
で名前の衝突が起こるだけです。 なし、定義することはできません:あなたが実際にやるべきことは、あなたが求めてきました実際の質問に取得するには、言った、あなたのN
タイプとこれらの標準クラスをインスタンス化、すなわち
instance Show N where
show n = ...
instance Read N where
readsPrec _ str = ...
∀ n . (n->n) -> n->n
のような多型の場合、任意ののインスタンスが分かりやすくなります。コンパイラはこれを(Int->Int) -> Int->Int
のようなより具体的な型と区別することになっていますか、より一般的なもの、例えば∀ n m . (n->m) -> n->m
?それはかなり絶望的です。 正しいのことは、それを新しいタイプでラップすることです。普遍的な定量化を隠し、コンパイラがN
を他の型と正しく区別できるようにします。
代わりに、あなただけの直接/歩留まりN
を受け入れる単相機能を書き込むことができます。
showChurch :: N -> String
showChurch n = ...
readsPrecChurch :: Int -> ReadS N
readsPrecChurch _ str = ...
実際には後者の方が既に型システムのための多すぎる:ReadS N
は
readsPrecChurch :: Int -> String -> [(∀ n . (n->n) -> n->n, String)]
の略です
リスト内のユニバーサル定量化?ええとああ。それは過酷なタイプです。 GHCには-XImpredicativeTypes
の拡張機能がありますが、実際には機能しません。
ここでも、多型を公開しないことでこれらの問題を回避できます。Rank-Nタイプ(特にレンズ)にはいくつかの用途がありますが、ほとんどの場合、それらは完全に過剰で不必要です。そのような教会の数字を実際に使用する正当な理由は決してありません。
newtype N = Church { getChurch :: ∀ n . (n->n) -> n->n }
任意のインスタンスまたは機能を問題なく定義できます。そして、実質的に
は、なぜあなたは 'newtype'を使用したくない...単に同じように良いことは勿論である整数に来るすべての標準のインスタンスと
やって、話しますか? – ErikR
newtypeやデータを使っているなら 'newtype N = N(n - > n) - > n - > n' 'と書いて'(+)(N a)(N b) a + bをアンボックスすることなく '(+)= \ ab - > stuff'の代わりに' stuff = 'を使います。 – CheeseLollipop
現行のGHCでは忍容性を避けることをお勧めします。 'newtype'や' data'を使うことはできません。 (また、 'newtype'を扱う方がずっと簡単になるような、安全な変換を探します)。 – chi