【发布时间】:2019-07-02 20:02:13
【问题描述】:
我正在尝试学习 Haskell,但我遇到了一些问题。到目前为止,我已经明白函数签名符合这个约定:
<name> :: <type constraint A> => <input type A> -> <input type B> -> .. <input type X> -> <return type>
所以,我目前理解的一些例子是:
-- Returns input + 2
add2 :: Int -> Int
add2 x = x + 2
-- Returns the result of applying a function that takes an int and returns an int on an input int
adds2 :: (Int -> Int) -> Int -> Int
adds2 func x = func x
-- Returns a String with "Hello" prepended to the front
sayHello :: String -> String
sayHello name = "Hello " ++ name
然后我遇到了这件事,这让我很困惑:
mate :: RandomGen g => Gene -> Gene -> Rand g Gene
我知道函数名称是mate,它有一个类型约束,其中g 必须是RandomGen 类型,然后它将两个Gene 类型的值作为输入。
然而,真正让我困惑的是返回类型。您如何解释这一点,任何人都可以向新手 Haskeller 解释一下吗?
【问题讨论】:
-
您的描述看起来正确。对于最后一种类型,请注意
Rand g Gene是一个单子类型,通过将单子Rand g应用于Gene类型获得。如果您还不熟悉 monad,那么要完全理解其后果并不容易。尽管如此,在英语中,Rand g Gene的值是对能够读取和写入类型为g的 RNG 状态变量并生成Gene值作为结果的计算的描述。更简洁地说,mate返回一个Gene,但结果是随机的,所以它不是一个常规的确定性函数.. -
啊,可怕的 monad.... 每次我试图陷入 Haskell 时,我都会碰到这个“Monad”墙,我读过的所有资源都接近掌握这个概念但它似乎从来没有点击过:-(
-
您实际上并不需要了解有关 Monads 的任何事情来理解类型签名。您只需要知道
Rand是一个“类型构造函数”,它接受2 个参数来创建一个“具体”类型。从技术上讲,我们说Rand是一个“种类”为* -> * -> *的类型(您也可以看到写为Type -> Type -> Type),这完全类似于具有a -> b -> c类型的函数——它是一个“ types”,它需要 2 种类型并产生另一种。Maybe是一个简单的例子,你可能已经知道了 - 它有一种* -> *(它需要 1 个类型参数)。 -
将约束读取为“
g必须具有类型类RandomGen的 instance”。
标签: haskell