gpt4 book ai didi

多参数函数的 Haskell 类型声明

转载 作者:行者123 更新时间:2023-12-05 00:41:16 25 4
gpt4 key购买 nike

我正在浏览 this包含此示例的 Haskell 简介:

data Tree a             = Leaf a | Branch (Tree a) (Tree a) 

它所说的本质上也是定义类型:

Branch                  :: Tree a -> Tree a -> Tree a
Leaf :: a -> Tree a

我理解 Leaf 定义是说它将 a 映射到 aTree。但我不理解分支定义,我将其读作“分支将 aTree 映射到 aTree code> 到 aTree 听起来不正确。这是因为所有 Haskell 函数默认都会被柯里化(Currying)吗?

最佳答案

没有。如果它有这样的签名:

Branch :: (Tree a, Tree a) -> Tree a

那么你应该给它一个元组,然后像这样调用构造函数:

Branch (tree1,tree2)

Branch 有一个签名:

Branch :: Tree a -> Tree a -> Tree a

或带有显式括号:

Branch :: Tree a -> (Tree a -> Tree a)

因此,当您向 Branch 提供第一个参数时,例如 Branch tree1,签名是:

(Branch t1) :: Tree a -> Tree a

当你最终输入第二个参数 t2 时,它的类型将折叠为:

((Branch t1) t2) :: Tree a

一个更方便的例子是(+),它不是一个构造函数,而是一个函数。 (+) our 加上 (+) 有签名

(+) :: Int -> Int -> Int

(Haskells plus 更通用一点,但我们现在不考虑这个)。

如果你现在写 (5+) 你已经将你的函数专门化为一个函数:

(5+) :: Int -> Int

换句话说,您构造了一个 new 函数,它将 5 添加到给定的数字。


由于 (a,b) -> ca -> b -> c 的签名有点等价,Haskell 提供了 curryuncurry功能:

curry :: ((a, b) -> c) -> a -> b -> c
uncurry :: (a -> b -> c) -> ((a, b) -> c)

如果您决定需要为 Branch 提供一个额外的构造函数,该构造函数应该被提供一个元组,那么您可以构造这样的构造函数:

branchTuple :: (Tree a, Tree a) -> Tree a
branchTuple = uncurry Branch

关于多参数函数的 Haskell 类型声明,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36914494/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com