为什么我可以使用纯函数转换为applicative

zer*_*ing 1 haskell

我有以下类型定义:

  data Hello a b =  Hi a
                  | Sali b
                  deriving (Show, Eq) 
Run Code Online (Sandbox Code Playgroud)

它不是一个实例,Applicative但我仍然可以用pure它来转换Applicative为什么?

*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
Run Code Online (Sandbox Code Playgroud)

当我尝试:

*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
Run Code Online (Sandbox Code Playgroud)

很清楚,因为它不是一个Applicative实例.

che*_*ner 6

由于您没有Applicative特别指定任何类型,ghci因此默认为IO,即pure $ Hi 34返回类型的值Num a => IO (Hello a b).也就是说,Hello a b不是fa -> f a,而是a.

通过为值指定各种函子,您可以更明确地看到Hello a b由任意类型包装的类型:ApplicativeApplicative

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]
Run Code Online (Sandbox Code Playgroud)