سؤال

Let's say I have a function that takes a list of function-list pairs, and maps the function in each pair onto the list in the pair, for example:

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

Is there a way of implementing myFunction so that the code I provided above will work as is without any modifications?

My problem is I can't figure out how to implement myFunction because the types of each sub-list could be different (in my example I have a list of strings ["DAY", ONE"], and a list of numbers: [1,2]). I know that each function in the list will convert its list into a list of strings (so the final list will have type [[Char]]), but I don't know how to express this in Haskell.

هل كانت مفيدة؟

المحلول

You can do it with existential types

{-# LANGUAGE ExistentialQuantification #-}

data T = forall a b. Show b => (:?:) (a -> b) [a]

table =
    [ ("SOME"++) :?: ["DAY","ONE"]
    , (show)     :?: [1,2]
    , (+1)       :?: [2.9, pi]
    ]

And run it as:

apply :: T -> String
apply (f :?: xs) = show $ map f xs

main = print $ map apply table

نصائح أخرى

You want to use existential quantification to define a type that can hold any value as long as it is a member of the Show typeclass. For example:

{-# 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

And now in ghci:

*Main> f [S 1, S True, S 'c']
["1","True","'c'"]

You won't be able to run the code in your question without modification, because it contains a heterogeneous list, which the Haskell type system forbids. Instead you can wrap heterogeneous types up as a variant type (if you know in advance all the types that will be required) or as an existentially quantified type (if you don't know what types will be required, but you do know a property that they must satisfy).

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top