2016-05-10 27 views
1

最近haskellを学び始めました。関数定義に関数型を宣言するのが混乱しています。例えば、我々はfoldr関数を定義する場合:、したがってfoldr(+)0 [1,2,3,4] =合計を関数型をhaskellの関数定義で宣言する

foldr :: (a->b->b)->b->[a]->b 
foldr f v [] = v 
foldr f v (x:xs) = f x (foldr f v xs) 

を[1,2,3,4] = 10

私の質問は:私は定義の文字の選択/要件を説明するための場所を見つけることができませんでした

foldr :: (a->a->a)->a->[a]->a 
OR: 
foldr :: (a->b->c)->x->[y]->z 

:私はちょうどのようなものに変更することができます。ありがとう!


アップデート: 私はそれをテスト:

foldr :: (a->b->c)->x->[y]->z 

は以下のERRガット:まですべてを変えた場合

Couldn't match type `y' with `a' 
    `y' is a rigid type variable bound by 
     the type signature for folderr :: (a -> b -> c) -> x -> [y] -> z 
     at test.hs:3:1 
    `a' is a rigid type variable bound by 
     the type signature for folderr :: (a -> b -> c) -> x -> [y] -> z 
     at test.hs:3:1 

を、それが動作します。私はここでいくつかのポイントを欠いている必要があります。


@ sepp2kさんのコメントで説明されています。だから、> Falseの

- >真 folderr(myop)トゥルー[3,2、-1] -

 folderr :: (a->b->b)->b->[a]->b 
    folderr f v [] = v 
    folderr f v (x:xs) = f x (folderr f v xs) 


    myop :: Int -> Bool -> Bool 
    myop x y | x > 0 = True && y 
       | otherwise = False && y 

folderr(myop)トゥルー[3,3,222]:私は、次の簡単な例を使用してテストa、bは型が異なるかどうかを意味します。

+0

'a'の両方を' y'に置き換えると、うまくいくでしょう。しかし、「a」と「y」のどちらか一方を「y」と呼ぶことによって、それらが異なる可能性があります。しかし、関数の定義はそれらを同じものとして扱うので、エラーが発生します。 – sepp2k

答えて

3

タイプ変数の具体的な名前は関係ありません。タイプはa -> b -> cx -> y -> zfoo -> bar -> bazは完全に同等です。

同じタイプの変数を複数回使用するか、異なるタイプの変数を使用するかは重要です。つまり、a -> ba -> aとは異なるタイプです。 a -> bはすべての4つに一致することになるのに対し、コンクリート型Int -> IntString -> StringInt -> StringString -> Inta -> aからのみ(それぞれa = Inta = Stringで)最初の二つに一致することになるので、具体的a -> bがより一般的です。

+0

ありがとうございます!今私にとって意味がある。私は例を使ってそれをテストしました。 – ohmygoddess

関連する問題