不完整的类型签名 [英] Incomplete type signature
问题描述
可以说我们有一个像下面的f这样的函数,它返回一个monad。然而,如果你看到 Int
,假装它是一个非常复杂的类型。
Lets say we've got a function like f below, that returns a monad. However, where you see Int
, pretend it's a really complicated type.
f :: (Monad m) => m Int -- Pretend this isn't Int but something complicated
f = return 42
现在可以说我们要强制这个成为 Maybe
monad。我们不需要写完整类型的 f
来做到这一点,我们可以做到以下几点:
Now lets say we want to force this into the Maybe
monad. We don't need to write the full type of f
to do this, we can just do the following:
g :: Maybe a -> Maybe a
g = id
main = print $ (g f)
虚函数 g
强制 f
变成也许
。
我觉得上面比较乱。
I think the above is rather messy. What I'd rather write is this:
main = print $ (f :: Maybe a)
但它会失败并显示以下错误:
But it fails with the following error:
Couldn't match expected type `a' against inferred type `Int'
`a' is a rigid type variable bound by
the polymorphic type `forall a. Maybe a' at prog.hs:7:16
Expected type: Maybe a
Inferred type: Maybe Int
In the second argument of `($)', namely `(f :: Maybe a)'
In the expression: print $ (f :: Maybe a)
有没有办法做到上面的 g
以不太复杂的方式做,而不需要创建一个新的函数?我不想写 f :: Maybe Int
,因为如果返回类型改变,它就成为一个维护问题。 GHC扩展可以在答案中找到答案。
Is there a way to do what g
above does in a less messy way that doesn't involve creating a new function? I don't want to write f :: Maybe Int
, as it becomes a maintenance problem if the return type changes. GHC extensions are okay in answers.
推荐答案
使用 asTypeOf
。它将第一个参数与第二个参数的类型统一起来,返回第一个参数。它只是 const 的类型限制版本,但对于这种情况很有用。
Use asTypeOf
. It returns the first argument while unifying its type with that of the second. It's just a type-restricted version of const
, but useful for situations like this.
main = print $ f `asTypeOf` (undefined :: Maybe a)
这篇关于不完整的类型签名的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!