gpt4 book ai didi

haskell - 具有默认字段且需要与其配合使用的函数的数据类型

转载 作者:行者123 更新时间:2023-12-03 05:07:30 25 4
gpt4 key购买 nike

假设我有一个数据类型

data FooBar a = Foo String Char [a]
| Bar String Int [a]

我需要创建这种类型的值并给出空列表作为第二个字段:

Foo "hello" 'a' []

Bar "world" 1 []

1)我在代码中的任何地方都这样做,我认为如果我能以某种方式省略空列表部分并隐式分配空列表,那就太好了。这可能吗?类似于其他语言中的默认函数参数。

2) 由于这个 [] “默认”值,我经常需要一个部分构造函数应用程序,该应用程序会生成一个采用前两个值的函数:

mkFoo x y = Foo x y []
mkBar x y = Bar x y []

有没有“更好”(更惯用等)的方法来做到这一点?避免定义新函数?

3)我需要一种将内容添加到列表中的方法:

add (Foo u v xs) x = Foo u v (x:xs)
add (Bar u v xs) x = Bar u v (x:xs)

这是惯用的做法吗?只是一个通用功能?

正如你所见,我是一个初学者,所以这些问题可能没有什么意义。希望不会。

最佳答案

我会一一解答您的问题。

  1. Haskell 中不存在默认参数。它们根本不值得增加复杂性和构图损失。作为一种函数式语言,您在 Haskell 中进行了更多的函数操作,因此像默认参数这样的时髦性将很难处理。

  2. 当我开始使用 Haskell 时,我没有意识到的一件事是数据构造函数就像其他所有东西一样都是函数。在您的示例中,

    Foo :: String -> Char -> [a] -> FooBar a

    因此,您可以编写函数来填充其他函数的各种参数,然后这些函数将与 Foo 或 Bar 等一起使用。

    fill1 :: a -> (a -> b) -> b
    fill1 a f = f a
    --Note that fill1 = flip ($)

    fill2 :: b -> (a -> b -> c) -> (a -> c)
    --Equivalently, fill2 :: b -> (a -> b -> c) -> a -> c
    fill2 b f = \a -> f a b

    fill3 :: c -> (a -> b -> c -> d) -> (a -> b -> d)
    fill3 c f = \a b -> f a b c

    fill3Empty :: (a -> b -> [c] -> d) -> (a -> b -> d)
    fill3Empty f = fill3 [] f

    --Now, we can write
    > fill3Empty Foo x y
    Foo x y []
  3. lens包为此类问题提供了优雅的解决方案。不过,一眼就能看出这个包非常复杂。以下是如何调用镜头包的最终结果:

    _list :: Lens (FooBar a) (FooBar b) [a] [b]
    _list = lens getter setter
    where getter (Foo _ _ as) = as
    getter (Bar _ _ as) = as
    setter (Foo s c _) bs = Foo s c bs
    setter (Bar s i _) bs = Bar s i bs

    现在我们可以做

    > over _list (3:) (Foo "ab" 'c' [2,1]) 
    Foo "ab" 'c' [3,2,1]

    一些解释:当给定某种类型的 getter 和 setter 时,lens 函数会生成 Lens 类型。 Lens s t a b 是一种类型,表示“s 持有 a 并且 t 持有 b” code>。因此,如果你给我一个函数 a -> b,我就可以给你一个函数 s -> t”。这正是 over 所做的:你为它提供一个镜头和一个函数(在我们的例子中,(3:) 是一个将 3 添加到 List 前面的函数)并应用“镜头指示的位置”功能。这与仿函数非常相似,但是,我们有更多的自由(在本例中,仿函数实例有义务更改列表的每个元素,而不是对列表本身进行操作)。

    请注意,我们的新 _list 镜头非常通用:它在 FooBar 上工作得同样好,并且镜头包提供了除 over 之外的许多功能。 code> 用于做神奇的事情。

关于haskell - 具有默认字段且需要与其配合使用的函数的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/31702318/

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