Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/haskell/8.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Haskell 类型推断似乎是一种魔术_Haskell - Fatal编程技术网

Haskell 类型推断似乎是一种魔术

Haskell 类型推断似乎是一种魔术,haskell,Haskell,我有以下代码段,无法对其进行配置,它是如何工作的: embedded :: MaybeT (ExceptT String (ReaderT () IO)) Int embedded = return 1 怎么可能只给出一个数字,然后得到诸如类型签名之类的信息呢?编译器是如何做到这一点的 措辞的选择有点不幸。表达式return 1返回类型签名MaybeT(除了ptt字符串(ReaderT()IO))Int的情况并非如此 正如n.m.在注释中所写,如果您不提供类型,则表达式更一般: Prelude

我有以下代码段,无法对其进行配置,它是如何工作的:

embedded :: MaybeT (ExceptT String (ReaderT () IO)) Int
embedded = return 1

怎么可能只给出一个数字,然后得到诸如类型签名之类的信息呢?编译器是如何做到这一点的

措辞的选择有点不幸。表达式
return 1
返回类型签名
MaybeT(除了ptt字符串(ReaderT()IO))Int
的情况并非如此

正如n.m.在注释中所写,如果您不提供类型,则表达式更一般:

Prelude> embedded = return 1
Prelude> :type embedded
embedded :: (Num a, Monad m) => m a
通过使用类型进行注释,您可以明确地声明您想要的不是一般性的东西

具体地说,您需要类型
MaybeT(除了ptt字符串(ReaderT()IO))Int

return
如何工作<当
m
Monad
时,code>MaybeT ma是
Monad
,并且
return
的定义如下:

return = lift . return
return a = ExceptT $ return (Right a)
return   = lift . return
右侧的
return
是属于“内部”单子
Monad
return
函数,而
lift
MonadTrans
定义,并将基础单子值提升到
MaybeT

这解释了
MaybeT
值是如何创建的,但不是全部

在这种情况下,“内部”单子是
除了字符串(ReaderT()IO)
,它是另一个
单子(实际上是另一个
MonadTrans
)<代码>返回
的定义如下:

return = lift . return
return a = ExceptT $ return (Right a)
return   = lift . return
请注意,这是另一个嵌套的
return
,其中右侧的
return
属于另一个嵌套的
Monad

在这种情况下,嵌套的
Monad
ReaderT()IO
——另一个
MonadTrans
。它定义
return
如下:

return = lift . return
return a = ExceptT $ return (Right a)
return   = lift . return
还有另一个嵌套的
返回
,其中右侧的
返回
是为
IO
定义的
返回
(在这种特殊情况下)

所有这些都用
a
参数化,在本例中,您将其限制为
Int


因此
return1
首先获取纯值
1
并将其打包到
IO Int
中。然后将其提升到
ReaderT()IO Int
,它再次被打包成
ExceptT字符串(ReaderT()IO)Int
。最后,这个值被提升到
MaybeT

您忘记了
返回值
return
不是关键字:它是一个函数:
return::Monad m=>a->ma
。你说得对。编译器不会推断此类型签名。它将推断出一个更为普遍的结论。您提供了一个不太通用的签名来告诉编译器“嘿,我知道我在做什么,我想要这个”。但是如何成像,它是如何工作的?没有多少有效的方法
MaybeT(除了字符串(ReaderT()IO))
是单子。所以
MaybeT(除了字符串(ReaderT()IO))Int
是一个
Monad m=>m Int
。因此,由于函数有一个
return 1
,因此它调用与
MaybeT关联的
return
(除了ptt字符串(ReaderT()IO))
。这里没有类型推断。您已经告诉编译器嵌入的
类型是什么
return
将根据该类型的
return
定义,简单地生成该类型的值。