gpt4 book ai didi

haskell - 提取 Haskell 中的常见功能

转载 作者:行者123 更新时间:2023-12-03 07:57:11 28 4
gpt4 key购买 nike

请看下面的代码:

draw :: (Ord n, Show n) => StagedListVM n -> Widget n
draw state =
vLimit
(StagedListVM.rowsAmount state)
( renderList
( \_isSelected pairs ->
hBox $ map (someFunction _isSelected) pairs
)
(StagedListVM.isFocused state)
(StagedListVM.bricksList state)
)
where
someFunction _isSelected pair = StagedListVM.something

我还有两段类似的代码:

draw :: (Ord n, Show n) => UnstagedListVM n -> Widget n
draw state =
vLimit
(UnstagedListVM.rowsAmount state)
( renderList
( \_isSelected pairs ->
hBox $ map (someFunction _isSelected) pairs
)
(UnstagedListVM.isFocused state)
(UnstagedListVM.bricksList state)
)
where
someFunction _isSelected pair = UnstagedListVM.something

最后一个:

draw :: (Ord n, Show n) => TreeVM n -> Widget n
draw state =
vLimit
(TreeVM.rowsAmount state)
( renderList
( \_isSelected pairs ->
hBox $ map (someFunction _isSelected) pairs
)
(TreeVM.isFocused state)
(TreeVM.bricksList state)
)
where
someFunction _isSelected pair = TreeVM.something

如您所见,除了 draw 函数的第一个参数的类型不同之外,它们是相同的。我对 Haskell 有点陌生。现在,如果是某种命令式 OOP 语言,我会编写一个函数而不是 3 个函数,我们将其称为 superDraw 并将一些抽象接口(interface)作为参数传递给它。

如何将这 3 个函数包装在 Haskell 中的一个函数中?

谢谢。

最佳答案

It seems to be they are "Haskell/Function Programming" alternative to OOP's abstract interface idiom. This seems like forcing OOP stuff onto Functional Programming

这是一个很好的态度。事实上,人们经常在 Haskell 中使用类型类,通过类比 OO 语言来思考,而这实际上没有意义。然而,这并不是说类型类根本没有用处。

我首先要问自己的问题是:为什么 StagedListVM、UnstagedListVM 和 TreeVM 首先是三种不同的类型?如果它们在结构上相似并且可以完全互换使用(就像面向对象中的不同子类),那么与在其实现中具有一些变体数据的单一类型相比,这只会增加复杂性。如果您希望类型系统跟踪存在微小差异,您始终可以为此目的添加一个类型参数,而处理您类型的函数通常会忽略该类型参数。

即使这三个版本使用完全不同的实现,最好将“if-this-were-OO”方法简单地包装在一个简单的记录中。对于您的大部分代码来说,它看起来很像这样可能有意义:

data VM = VM { rowsAmount :: Int
, isFocused :: Bool
, ...
}

只有something似乎不适合这种方法,因为它不采用state参数。

对我来说,这表明这可能确实是一个适合类型类的用例:

class VM v where
rowsAmount :: v n -> Int
isFocused :: v n -> Bool
...
something :: Something (v n) ...

instance VM StagedListVM where
rowsAmount = StagedListVM.rowsAmount
...
instance VM UnstagedListVM where
...

这样,代码就可以轻松地在所有三种类型上实现多态:

draw :: (VM v, Ord n, Show n) => v n -> Widget n
draw state =
vLimit
(rowsAmount state)
( renderList
( \_isSelected pairs ->
hBox $ map (someFunction _isSelected) pairs
)
(isFocused state)
(bricksList state)
)
where
someFunction _isSelected pair = something

关于haskell - 提取 Haskell 中的常见功能,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/75760074/

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