2012-01-23 6 views
6

これはReflection-0.5から取られた最小の例です。 GHCiの中ハスケル:なぜこのタイプチェックですか?

{-# LANGUAGE Rank2Types, MultiParamTypeClasses, FunctionalDependencies, FlexibleInstances #-} 
{-# OPTIONS_GHC -fno-cse -fno-full-laziness -fno-float-in #-} 

import Control.Applicative 
import Data.Proxy 

newtype Zero = Zero Zero deriving (Show) 

class ReifiesNum s where 
    reflectNum :: Num a => proxy s -> a 

instance ReifiesNum Zero where 
    reflectNum = pure 0 

、私は次を得る:

>:t Zero 
Zero :: Zero -> Zero 

これは理にかなって:私はゼロを取り、ゼロを返すコンストラクタの種類を求めています。

>:t reflectNum 
reflectNum :: (ReifiesNum s, Num a) => proxy s -> a 

それはタイプだけゼロ型変数「プロキシs」を一致するため、私は

>let x = Just (undefined::Zero) 
>reflectNum x 

のようなものを書くことができます意味があります。最後に

、紛らわしい部分:

>:t (reflectNum Zero) 
(reflectNum Zero) :: Num a => a 

私は、コンストラクタゼロの種類::ゼロがどのように理解していない - >ゼロが明らか型変数「プロキシS」と一致しますが、ので、どうやらそれがありませんタイプ(reflectNum Zero)はちょうど「a」です。

この例を理解していただければ幸いです。また、関連する概念へのリンクを高く評価していただければ幸いです。

おかげ

答えて

11

それはあなたを投げ関数矢印のちょうど中置構文です。まず、わかりやすいケースの例を次に示します:Maybe Int。それはproxy sを一致させるために、我々は単に設定:

proxy = Maybe 
s = Int 

が今度は a -> bではなく Fun a bを書かれて、そしてそう Zero Fun Zero Zero(すなわち (Fun Zero) Zero)を入力していているふりをしてみましょう。 proxy(->) Zeroで、実際に

proxy = Fun Zero 
s = Zero 

などproxy s((->) Zero) Zero≡≡(->) Zero ZeroZero -> Zeroである:それはproxy sを一致させるために、我々は設定してください。

+0

「( - >)ゼロ」はなぜ有効なタイプですか?私は「> x = [something] ::(( - >)Zero)」のように書く方法を想像することはできません。私は意味があると思う。答えをありがとう! – crockeea

+3

@Eric '( - >)Zero'は有効な型ではありません。*型コンストラクタ*です。具体的な型を作るために別の型に適用する必要があります。 'たぶん'でも同じことが言えます。 'Maybe'型の値はありませんが、' Maybe Int'、 'Maybe [Double]'、 'Maybe(Maybe(Maybe Char))'などの値があります。同様に ' ( - >)Zero 'となりますが、 '( - >)Zero Zero'すなわち' Zero-> Zero'の値があります。 – Ben

+0

ありがとうございました。私は接頭辞と接頭辞の記法が不足していましたが、今は明らかです! – crockeea

関連する問題