试图理解haskell库中的类型
我正在努力理解hmap试图理解haskell库中的类型,haskell,compiler-errors,Haskell,Compiler Errors,我正在努力理解hmap module Main where import Control.Effect.Fresh import Control.Effect.Carrier a :: Fresh Maybe Int a = Fresh (\n -> Just 5) b :: Fresh Maybe [Int] b = fmap (\n -> [7::Int]) a f :: Maybe Int -> [] Int f mi = [1] c :: Fresh Mayb
module Main where
import Control.Effect.Fresh
import Control.Effect.Carrier
a :: Fresh Maybe Int
a = Fresh (\n -> Just 5)
b :: Fresh Maybe [Int]
b = fmap (\n -> [7::Int]) a
f :: Maybe Int -> [] Int
f mi = [1]
c :: Fresh Maybe Int -> Fresh [] Int
c = hmap f
main :: IO ()
main = do
putStrLn "Just testing types"
ghc错误:
• Couldn't match type ‘x’ with ‘Int’
‘x’ is a rigid type variable bound by
a type expected by the context:
forall x. Maybe x -> [x]
at src/Main.hs:16:5-10
Expected type: Maybe x -> [x]
Actual type: Maybe Int -> [Int]
• In the first argument of ‘hmap’, namely ‘f’
In the expression: hmap f
In an equation for ‘c’: c = hmap f
|
16 | c = hmap f
| ^
为什么x和Int不匹配?
hmap的类型签名为:
hmap :: Functor m => (forall x . m x -> n x) -> (h m a -> h n a)
我的f函数在我的代码中声明为:
f :: Maybe Int -> [] Int
f mi = [1]
为什么
mx->nx
和之间没有匹配,可能是Int->[]Int
正如您从hmap
的签名中看到的,它要求所有x都具有类型的函数。m x->n x
。其中的for all x
表示它需要对所有可能的x
工作,但您的函数只对Int
工作。它的类型是m Int->n Int
(其中m=Maybe
和n=[]
),但是hmap
需要mx->nx
,用于所有可能的x
为了将f
与hmap
一起使用,您需要以一种通用的方式对其进行定义,例如,它适用于任何参数类型
f :: forall x. Maybe x -> [] x
f (Just x) = [x]
f Nothing = []
(注意:
对于所有x.
在该签名中不是必需的,但我包含它是为了说明f
需要如何匹配hmap
的第一个参数)hmap
没有此类型
hmap :: Functor m => (m x -> n x) -> (h m a -> h n a)
但却有这种类型:
hmap :: Functor m => (forall x . m x -> n x) -> (h m a -> h n a)
区别在于,在第一个(假)类型中,您可以选择x
的值。在后一种类型中,由hmap
(而不是您)选择x
在代码中,您将f
传递给hmap
,这相当于选择了x=Int
,但不允许这样做。您需要定义一个f
,它能够处理任何x
,例如
f :: Maybe x -> [] x
f mi = []