【问题标题】:Haskell - heterogeneous arrays?Haskell - 异构数组?
【发布时间】:2017-09-23 06:05:58
【问题描述】:

我正在尝试用 99 个 Haskell 问题来学习 Haskell:

https://wiki.haskell.org/H-99:_Ninety-Nine_Haskell_Problems。 对于其中一个问题,我必须返回Element 的异构数组和(Int, Element) 形式的元组。由于 haskell 不允许在数组中存储异构数据,我能想到的最好的方法是

data Hetero a = Tuple (Int, a) | Elem a deriving (Show, Ord, Eq)

然后像这样写我的函数:

myFunk [a] -> [Hetero a] 

-- Rest of the function

但是我的结果看起来像这样:

[Tuple (2, 10), Elem 1]

有没有办法可以修改我的数据类型或函数以返回类似的东西

[(2, 10), 1] 

【问题讨论】:

  • [(2, 10), 1] 的类型是什么?
  • 我明白你的意思,认为它也应该是另一个用户定义的类型
  • 如果你只是想让它显示得很好,你可以将两者都映射到String,这样它就会变成["(2, 10)", "1"]。但是,您不能为此使用show 的默认实例,因为(IIRC)它将Tuple (2, 10) 呈现为"Tuple (2, 10)"
  • 这99个问题不过是麻烦。它们真的不是为 Haskell 编写的。你已经解决了问题;继续前进!
  • 正如@dfeuer 所写,您已经解决了问题。这就是在 Haskell 中完成的方式。

标签: haskell


【解决方案1】:

不,没有办法做到这一点。您所做的已经是最好和最惯用的解决方案。

【讨论】:

    【解决方案2】:

    如前所述,明确标记每个元素的类型是正确的做法。当您真正想要使用该列表时,这是有回报的,因为您可以简单地对元素进行模式匹配,然后在每个子句中确定您拥有哪些类型!

    但是,这并不意味着这样的列表必须始终写出 与那些冗长的构造函数名称。您可以通过选择不同的构造函数名称来节省大量样板文件,特别是 中缀构造函数

    data Hetero a = Int :* a | Elem a
    

    那么你的列表看起来像

    [2 :* 10, Elem 1]
    

    您甚至可以通过实例允许通过单个数字文字定义这些值

    instance (Num a) => Num (Hetero a) where
      fromIntegral = Elem . fromIntegral
    

    ...然后允许写入

    [2:*10, 1]
    

    但这可能不是一个好主意,因为Num 类型也应该支持加法、乘法等,我不确定是否可以为元组情况合理定义。如果你走这条路,你应该确保算术运算实际上表现得很好。

    【讨论】:

      【解决方案3】:

      但是我的结果看起来是这样的:

      (我的重点)

      您可以通过更改Hetero 的定义来解决该问题:

      data Hetero a = Tuple (Int, a) | Elem a deriving (Ord, Eq)
      
      instance Show a => Show (Hetero a) where
        show (Tuple (i, x)) = "(" ++ show i ++ ", " ++ show x ++ ")"
        show (Elem x) = show x
      

      现在Hetero 元素列表将按照您希望的方式显示:

      *Q46376603> [Tuple (2, 10), Elem 1]
      [(2, 10),1]
      

      【讨论】:

      • 这是可能的,但我不建议这样做。 show 的输出应该是有效的 Haskell 代码,但 [(2,10), 1] 仅在元素确实是纯元组而不是 Hetero 时才有效,如果你给这些纯元组一个 @ 987654328@ 实例,这显然是个坏主意。
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-11-09
      • 1970-01-01
      • 1970-01-01
      • 2019-01-09
      • 1970-01-01
      相关资源
      最近更新 更多