Haskell函数签名混乱

时间:2019-07-02 20:02:13

标签: haskell

我正在尝试学习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类型,然后它将两个{{ 1}}。

但是,真正让我感到困惑的是返回类型。您如何解释这一点,并且有人可以向新手Haskeller解释吗?

1 个答案:

答案 0 :(得分:5)

如果您定义了自己这样的数据类型

data MyType = A Int String

然后A(您的数据构造函数)将实际上是具有类型的函数

A :: Int -> String -> MyType

,您会这样称呼它以生成MyType的值。

A 42 "hello"

这就是数据构造函数。

Haskell还具有类型构造函数。 Rand是一个。就像函数值具有定义如何应用它们的函数类型一样,类型构造函数具有确定它们如何应用的“函数” 种类。像IntString这样的常规旧类型的类型被拼写为*Rand是类型构造函数,其类型为* -> * -> *:它接受两种类型并从中产生一个类型。

因此,当您将Rand应用于类型gGene时,将得到函数的返回类型,即Rand g Gene

有关更多信息,请参见this chapter of Learn You A Haskell

(“好,但是... Rand g Gene是什么?”,我听到你问。好吧,假设你的意思是this RandRand g Gene是代表计算的值如果您在能够运行Gene的事物(例如runRand)中运行它,则会产生Rand g。现在,这不是{{1 }},因为它确实发生了Rand g Gene是... dun dun dun ... monad!有关该概念的更多信息,您确实应该阅读类似{{3} } ...有很多准备工作可以向新手全面解释。)