首页 > 解决方案 > 试图理解 haskell 库融合效果中的类型

问题描述

我正在尝试理解 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]

m x -> n x为什么和之间不匹配Maybe Int -> [] Int

标签: haskellcompiler-errors

解决方案


从 的签名中可以看出hmap,它需要一个类型的函数forall x. m x -> n xforall x那里意味着它需要为所有可能x的工作,但你的功能只适用于Int。它具有类型m Int -> n Int(wherem=Mayben=[]),但hmap需要m x -> n x所有可能的x.

为了使用fwith hmap,您需要以通用方式定义它,以便它适用于任何参数类型,例如

f :: forall x. Maybe x -> [] x
f (Just x) = [x]
f Nothing = []

(注意:forall x.在此签名中不是必需的,但我包含它是为了说明如何f需要匹配 的第一个参数hmap


推荐阅读