我无法理解为什么以下代码可以正确编译:
f :: a -> Maybe a
f = return Just 3
return Just
有一种 Monad m => m (a -> Maybe a)
类型,所以我不确定为什么要传入 Int
unwraps monad。
你甚至可以对此感到有点疯狂:
f :: a -> Maybe a
f = return Just (Just . Just . Just . Just)
有人可以解释一下到底发生了什么吗?
谢谢
这里没有发生“展开”。只是有一个
(->) r
的 monad 实例,您可能将其称为 Reader
。
您可以通过在 ghci 中输入
:i (->)
来检查它是否存在:
ghci> :i (->)
type (->) :: * -> * -> *
type (->) = FUN Many :: * -> * -> *
-- Defined in ‘GHC.Types’
infixr -1 ->
instance Monoid b => Monoid (a -> b) -- Defined in ‘GHC.Base’
instance Semigroup b => Semigroup (a -> b) -- Defined in ‘GHC.Base’
instance Applicative ((->) r) -- Defined in ‘GHC.Base’
instance Functor ((->) r) -- Defined in ‘GHC.Base’
instance Monad ((->) r) -- Defined in ‘GHC.Base’
为我们的案例实例化这一点:
return :: a -> (r ->) a -- which is just a -> r -> a
--
Just :: x -> Maybe x
-- ==>
return Just :: r -> (x -> Maybe x) -- after substituting a = x -> Maybe x
-- ==>
return Just 3 :: x -> Maybe x -- after substituting r = Int
所以
return Just 3
变成了一种奇特的书写方式Just
。由于我们不使用 r
,您可以传递任何您喜欢的内容,甚至是 undefined
。
您正在使用阅读器单子
return
中的 (->) Int
,其定义为 const
。在这种情况下 return Just
的类型为 Int -> a -> Maybe a
。
f = return Just 3
= const Just 3
= Just