Haskell - 异构数组?

时间:2017-09-23 06:05:58

标签: haskell

我正在尝试用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] 

3 个答案:

答案 0 :(得分:4)

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

答案 1 :(得分:3)

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

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

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类型也应该支持加法,乘法等,我不确定可以为元组情况明确定义。如果你走这条路,你应该确保算术运算实际上表现得很好。

答案 2 :(得分:0)

  

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

(我的重点)

您可以通过更改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]