繁体   English   中英

Haskell 中的代数数据类型

[英]Algebraic Data Types in Haskell

你好,到目前为止我只使用过命令式编程,我正在学习 Haskell :)

我有以下代数数据类型:

data Day   = I | ... | XXXI deriving(Ord,Eq)    (Days in roman numerals)
data Month = Jan | ... | Dec deriving(Ord,Eq)   (Months abbreviated to 3 letters)
data Year  = 0 | ... | 2021                     (actually Ints)

我需要用这些做一些计算。 我的第一个想法是将天数和月数映射到整数并从那里进行计算。 例如:

dayConversionMap   = [(I,1), (II,2), (III,3), (IV,4), ... , (XXXI,31)]
monthConversionMap = [(Jan,1), (Feb,2), (Mar,3), ... , (Dec,12)]

我的问题是:

  1. 这是解决我的问题的好方法吗?
  2. 鉴于我有这些地图,我如何在函数中将天/月转换为整数。

提前致谢! :)

不要,我再说一遍不要自己计算日期和时间。 运送到一个好的图书馆 另请参阅程序员认为时间错误的不完整原因列表。

回答您的问题:

有很多方法可以做你正在寻找的东西,正如已经指出的那样,一种实用的方法是使用图书馆。 更好的是,找到一个库并阅读源代码。 Hoogle是你的朋友。


但是为了学习 Haskell 的目的:

您可以尝试提供一个函数,而不是手动映射它们。 并且因为这是您希望更多类型共享的行为,您可以创建一个类型类。 一种天真的(可能是说教,不太实用,可能玩起来很有趣)的方式是:

  1. 定义一个提供与 Int 相互转换的方法的类,我们称之为ToInt 现在你有一个通用的接口来从你的所有类型中获取这种行为
class ToInt a where
  toInt   :: a -> Int
  fromInt :: Int -> Maybe a

现在您可以为您的类型实现tofrom并使用它们进行转换。

instance ToInt Day where
  toInt x =  
    case x of
      I -> 1
      II -> 2 
--    ...

  fromInt x = 
    case x of 
      1 -> I
--    ...

instance ToInt Month where 
-- ...
calculation :: Day -> Month -> Year -> Int
calculation d m y = doSomething (toInt d) 
  where 
    doSomething :: Int -> Int 
    doSomething = ...

请注意,这是一个简单但糟糕的示例。

您可以看到这两种实现的乏味本质,以及您从类型检查器中获得的有限帮助。 但是,一旦您开始实施某事,您就会了解哪些有效,哪些无效。 然后你可以在实际库中搜索其他人如何处理这些问题, 例如

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM