假设我有一个函数,它接受函数列表对的列表,并将每对中的函数映射到对中的列表中,例如:
myFunction [("SOME"++,["DAY","ONE"]), (show,[1,2])] == [["SOMEDAY", "SOMEONE"],["1","2"]]
有没有办法实现myFunction,以便我上面提供的代码可以正常工作而不做任何修改?
我的问题是我无法弄清楚如何实现myFunction,因为每个子列表的类型可能不同(在我的例子中我有一个字符串列表[“DAY”,ONE“]和一个列表数字:[1,2])。我知道列表中的每个函数都会将其列表转换为字符串列表(因此最终列表将具有类型[[Char]]),但我不知道如何表达这在Haskell。
答案 0 :(得分:4)
你可以用存在类型
来做{-# LANGUAGE ExistentialQuantification #-}
data T = forall a b. Show b => (:?:) (a -> b) [a]
table =
[ ("SOME"++) :?: ["DAY","ONE"]
, (show) :?: [1,2]
, (+1) :?: [2.9, pi]
]
并按以下方式运行:
apply :: T -> String
apply (f :?: xs) = show $ map f xs
main = print $ map apply table
答案 1 :(得分:1)
您希望使用存在量化来定义可以包含任何值的类型,只要它是Show
类型类的成员即可。例如:
{-# LANGUAGE ExistentialQuantification #-}
data S = forall a. Show a => S a
instance Show S where
show (S s) = show s
f :: [S] -> [String]
f xs = map show xs
现在在ghci:
*Main> f [S 1, S True, S 'c']
["1","True","'c'"]
如果没有修改,您将无法在您的问题中运行代码,因为它包含异构列表,Haskell类型系统禁止该列表。相反,您可以将异构类型包装为变体类型(如果您事先知道将需要的所有类型)或作为存在量化类型(如果您不知道将需要哪些类型,但您确实知道属性)他们必须满足。)