gpt4 book ai didi

haskell - 如何指定内联类型中使用的类型变量,是否与函数定义中使用的类型变量相同?

转载 作者:行者123 更新时间:2023-12-04 22:46:16 25 4
gpt4 key购买 nike

(如果我的术语有误,请见谅)。

我正在尝试编写一个处理异常的包装函数:如果给定 IO Action 抛出,返回 Nothing (当然在 IO 上下文中),但是如果给定的 IO操作成功,返回Just v .

tryMaybe :: IO a -> IO (Maybe a)
tryMaybe action = do
result <- (try action) :: IO (Either SomeException a)
return $ case result of
Left _ -> Nothing
Right v -> Just v

这会导致编译器错误消息:
  Couldn't match type `a' with `a1'
`a' is a rigid type variable bound by
the type signature for tryMaybe :: IO a -> IO (Maybe a)
at src/Database.hs:33:13
`a1' is a rigid type variable bound by
an expression type signature: IO (Either SomeException a1)
at src/Database.hs:35:15
Expected type: IO a1
Actual type: IO a
In the first argument of `try', namely `action'

我猜类型变量 a第一行与 a 不同在第三行 - 它们恰好在源代码中具有相同的名称,并且编译器已将其重命名 a1在错误消息中。

那么我如何告诉 Haskell 这些是相同的类型呢?

最佳答案

您需要启用 ScopedTypeVariables 扩展,并将顶级函数的类型签名更改为以 forall a . 开头:

{-# LANGUAGE ScopedTypeVariables #-}

...

tryMaybe :: forall a . IO a -> IO (Maybe a)
...
forall语法带来了类型变量 a进入 tryMaybe 的整个主体的范围,而不是仅限于默认的类型签名。这主要是历史异常,而不是故意设计。

关于haskell - 如何指定内联类型中使用的类型变量,是否与函数定义中使用的类型变量相同?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24395881/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com