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