gpt4 book ai didi

haskell - 在haskell中设计具有大量构造函数的数据类型

转载 作者:行者123 更新时间:2023-12-04 21:18:12 26 4
gpt4 key购买 nike

有没有另一种方法来写这样的东西:

data Message = Message1 Int Int ByteString
| Message2 Double Int Int
| Message3 Double Double
.....
| Message256 CustomType

构造函数太多,很难使用记录语法。我真正想做的是编写一个解析器,是否有一些替代方法?
parse :: Bytestring -> Parser Message

最佳答案

首先,有一个 Plan为 Haskell 实现重载的记录字段,这将允许在不同的记录中使用相同的名称,并且您只需在编译器无法自行解决的情况下明确指定您想要的名称。

话虽如此 ...

我发现处理这个问题最可靠、最方便的方法是 每个消息类型一个 Haskell 类型 .

你将会拥有:

data Message1 = Message1 Int Int ByteString -- can use records here
data Message2 = Message2 Double Int Int
data Message3 = Message3 { m3_a :: Double, m3_b :: Double }
-- .....
data Message256 = Message256 CustomType

-- A sum type over all possible message types:
data AnyMessage = M1 Message1
| M2 Message2
| M3 Message3
-- ...
| M256 Message256

这样做的好处包括:
  • 您可以使用记录(仍然必须使用不同的前缀,但这通常已经足够了)
  • 它比跨构造函数共享记录安全得多:
    data T = A { field :: Int }
    | B { field :: Int }
    | C { bla :: Double } -- no field record

    print (field (C 2.3)) -- will crash at runtime, no compiler warning
  • 您现在可以编写仅适用于某些消息类型的函数。
  • 您现在可以编写仅适用于消息类型的子集(例如其中 3 个)的函数:您只需要另一种和类型。
  • 处理这个的代码还是很优雅的:
    process :: AnyMessage -> IO ()
    process anyMsg = case anyMsg of
    M1 (Message1 x y bs) -> ...
    ...
    M3 Message3{ m3_a, m3_b } -> ... -- using NamedFieldPuns

  • 我在生产中多次使用这种模式,它产生了非常健壮的代码。

    关于haskell - 在haskell中设计具有大量构造函数的数据类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/17844766/

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