3

假设我有一个函数,它采用函数列表对的列表,并将每对中的函数映射到对中的列表上,例如:

myFunction [("SOME"++,["DAY","ONE"]), (show,[1,2])] == [["SOMEDAY", "SOMEONE"],["1","2"]]

有没有办法实现 myFunction 以便我上面提供的代码无需任何修改就可以正常工作?

我的问题是我不知道如何实现 myFunction 因为每个子列表的类型可能不同(在我的示例中,我有一个字符串列表 ["DAY", ONE"] 和一个数字列表:[ 1,2]). 我知道列表中的每个函数都会将其列表转换为字符串列表(因此最终列表将具有 [[Char]] 类型),但我不知道如何在 Haskell 中表达这一点.

4

2 回答 2

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
于 2012-05-11T12:54:17.917 回答
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 类型系统所禁止的。相反,您可以将异构类型包装为变体类型(如果您事先知道将需要的所有类型)或作为存在量化类型(如果您不知道需要哪些类型,但您确实知道一个属性他们必须满足)。

于 2012-05-11T12:57:29.897 回答