试图理解haskell库中的类型

试图理解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

我正在努力理解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 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 = []