2017-08-22 10 views
1

を応用的に変換するために、純粋な機能を使用することができます。は、なぜ私は型定義以下のいる

data Hello a b = Hi a 
        | Sali b 
        deriving (Show, Eq) 

をし、それがApplicativeのインスタンスではありませんが、私はまだApplicativeなぜに変換するpureを使用することができますか?

*ExercisesTraversable Data.Monoid Control.Applicative> :t pure $ Hi 34 
pure $ Hi 34 :: (Num a, Applicative f) => f (Hello a b) 

*ExercisesTraversable Data.Monoid Control.Applicative> pure $ Hi 34 
Hi 34 

そして、私が試してみてください。

*ExercisesTraversable Data.Monoid Control.Applicative> (Sali (*2)) <*> (Sali 4) 

<interactive>:23:1: error: 
    * Non type-variable argument 
     in the constraint: Applicative (Hello a) 
     (Use FlexibleContexts to permit this) 
    * When checking the inferred type 
     it :: forall b a. (Num b, Applicative (Hello a)) => Hello a b 

それはApplicativeインスタンスではないので、明らかです。

答えて

6

あなたは、特に任意Applicativeタイプを指定していないので、ghciNum a => IO (Hello a b)の値を返すpure $ Hi 34すなわち、IOにデフォルト設定されています。つまり、Hello a ba -> f aにはfではありません。aです。

あなたはHello a bは、値のために、様々なApplicativeファンクタを指定することで、任意のApplicativeによってラップ型指定されていることをより明確に見ることができます。

Prelude> (pure $ Hi 34) :: Either String (Hello Int b) 
Right (Hi 34) 
Prelude> (pure $ Hi 34) :: Maybe (Hello Int b) 
Just (Hi 34) 
Prelude> (pure $ Hi 34) :: [Hello Int b] 
[Hi 34] 
+0

私は前書き 'Prelude>を見ています:純粋な$ Hi 34 純粋な$ Hi 34 ::(Num a、Applicative f)=> f(Hello a b)'私は 'IO'型を見ることができません。どうして? –

+1

'IO'はあなたがそれを評価しようとするとき、デフォルトとしてのみ使用されます。 – chepner

4

あなたがpure xを呼び出すと、それはApplicativeする必要があることをxではありませんが、全体pure x発現。 pureタイプをご覧ください:

Prelude> :t pure 
pure :: Applicative f => a -> f a 

を参照してください。 aを渡しますが、Applicativeという制約はfにあり、結果にはfしか表示されません。ですから、それはクラスApplicativeでなければなりません。そして、@chepnerが言ったように、GHCiプロンプトのデフォルトはIOです。これはApplicativeです。

関連する問題