2017-08-22 23 views
2

私はApplicativeの式を以下していると私はそれが間違っている知っている:コンパイラは何を意味しますか?

Prelude> [Just (*2), Just (+9)] <*> [(Just 3),(Just 4), (Just 5)] 

をし、コンパイラは文句:

<interactive>:2:2: error: 
    * Couldn't match expected type `Maybe Integer -> b' 
        with actual type `Maybe (Integer -> Integer)' 
    * Possible cause: `Just' is applied to too many arguments 
     In the expression: Just (* 2) 
     In the first argument of `(<*>)', namely `[Just (* 2), Just (+ 9)]' 
     In the expression: 
     [Just (* 2), Just (+ 9)] <*> [(Just 3), (Just 4), (Just 5)] 
    * Relevant bindings include it :: [b] (bound at <interactive>:2:1) 

コンパイラが言って何をしようとしているのでしょうか?

このエラーメッセージ:

* Couldn't match expected type `Maybe Integer -> b' 
       with actual type `Maybe (Integer -> Integer)' 

それは表現のこの部分[Just (*2), Just (+9)]を意味しますか?

(<*>) :: [] (Maybe Integer -> b) -> [] (Maybe Integer) -> [] b 

bが型を持っている必要があります。

(<*>) :: f (a -> b) -> f a -> f b 

は、上記ListMaybe型コンストラクタでそれを代用:

はの関数 (<*>)の署名を見てみましょうか?

+1

これは、いくつかの 'b'に対して' Maybe Integer - > b'型を期待しますが、 'Maybe(Integer - > Integer)'を与えています。しかし、それは単にコンパイラが述べたことを述べています。このエラーのどの部分を誤解していますか? (エラーは実際に '[Just(* 2)、Just(+9)] 'を参照していますが、エラー自体にも明記されています。フリータイプ変数) – user2407038

+0

恐ろしい、今私は参照してください。 '多分(整数 - >整数)'は関数ではなく、むしろ型だけです。ありがとう。 –

答えて

3

レッツ・代替より慎重

(<*>) :: (Applicative f) => f (a -> b) -> f a -> f b 
[Just (*2), Just (+9)] :: [Maybe (Int -> Int)] --wlog 
[Just 3, Just 4, Just 5] :: [Maybe Int] 

のでf = []、:

(<*>) :: [a -> b] -> [a] -> [b] 

しかし、今、我々は[Maybe (Int -> Int)]に対して[a -> b]に一致するようにしていると、それは不可能だ - 機能とMaybeにすることはできません同じ。あなたはの下でファンクションアプリケーションをしようとしています。ただ1つではなく、2つのファンクタです。私。あなたは

f (g (a -> b)) -> f (g a) -> f (g b) 

幸いなタイプのものが必要になり、それは作るのは簡単です:liftA2 (<*>)

また、何か気が欲しいのであれば、代わりに複合ファンクタCompose [] Maybeを操作することもできます。

getCompose $ Compose [Just (*2), Just (+9)] <*> Compose [Just 3, Just 4, Just 5] 

(しかしComposeがクールですあなたはすぐに結果をgetComposeが、あなたが書いているものは何でもプログラムに重要な抽象化としてそれを使用しないときである。)

2

間違っ置換がここにあります:Num a => [Maybe (a -> a)]

List(<*>) :: f (a -> b) -> f a -> f bfですのでです:

(<*>) :: [] (Maybe Integer -> b) -> [] (Maybe Integer) -> [] b 

[Just (*2), Just (+9)]は、次のタイプがあります。

(<*>)の種類によると、あなたが持つことができます。

[(*2), (+9)] <*> [2, 3] 

それとも

Just (*2) <*> Just 2 

[]Maybeをちょうど使用して、Applicativeの相応これらの式でコンテキスト、両方ではなくなります(<*>)

次の難解な表現がコンパイルされます。

[(Just (*2) <*>), (Just (+9) <*>)] <*> [(Just 3), (Just 4), (Just 5)] 

しかし、私はそれがあなたが探しているものであるかどうかはわかりません。これ

3

コンパイラは、この部分を指していますあなたのコードの(In the expression: Just (* 2)):

[Just (*2), Just (+9)] <*> [(Just 3),(Just 4), (Just 5)] 
^^^^^^^^^ 

またJust (*2)の実際の型がMaybe (Integer -> Integer)であることを言っているが、あなたがそれを使用している方法は、の値が必要Maybe Integer -> b(一部のタイプはb)。

あなたは

(<*>) :: f (a -> b) -> f a -> f b 

の種類を見れば、あなたは最初の引数は関数型a -> bに適用fいくつかのタイプのコンストラクタでなければならないことがわかります。値のリストがあるので、f[]です。

したがって、最初の引数は関数のリストでなければなりませんが、持っているものはMaybeのリストです。そのため、このコードはエラーです。

残りのエラーメッセージは、<*>の第2引数([(Just 3),(Just 4), (Just 5)])(第1引数の関数リストの場合)です。つまり、コンパイラは、タイプf aの値を必要とし、[(Just 3),(Just 4), (Just 5)]を与えたので、f = [],a = Maybe Integerと推定されます。

したがって、最初の引数f (a -> b)のタイプは[] (Maybe Integer -> b)(これは[Maybe Integer -> b]と同じです)になります。ここではbは完全に無料です。任意の結果タイプを使用できます。f b[b](結果のリスト))が<*>から返されます。

0

2つのファンクタがある命令

Prelude> [Just (*2), Just (+9)] <*> [(Just 3),(Just 4), (Just 5)] 
います。外側は List、内側は Maybeです。したがって、 <*>の適用操作を2つのリストの間に置くと、最初のリストには、関数型要素が含まれています。

Prelude> [(+1),(*2)] <*> [1,2] 
[2,3,2,4] 

は、しかし、あなたの命令で最初のリストはいくつかのMaybe値が含まれています。これは、リストを適用ファンクタとして認定するものではありません。しかし、リストの要素はタイプMaybe (a -> b)です。つまり、リストそのものではなく、内容は応用的なファンクタです。したがって、リストを適用リストにするには、適用可能なMaybe値を、アプリケーションMaybe (a -> b)Maybe aに置き換えて、Maybe bという別の言葉で置き換えます。つまり、<*>の演算子になります。

コードを次のように書き換えると、期待される結果が得られます。

Prelude> (<*>) <$> [Just (*2), Just (+9)] <*> [(Just 3),(Just 4),(Just 5)] 
[Just 6,Just 8,Just 10,Just 12,Just 13,Just 14] 
関連する問題