How to iterate through a heterogeneous recursive value in Haskell

I saw the HList package, but I think it is too complicated for what I need.

I have it:

data a :*: b = a :*: b deriving (Show, Eq)

and I can add the following to it successfully:

prepend :: a -> b -> a :*: b
prepend a b = a :*: b

but I would like to sort through the “list” somehow and do something with the elements, but I'm not sure how to do it.

+3
source share
2 answers

Note that you can already iterate over a list in two ways:

ghci> let hetlist = (1 :: Int) :*: ("two" :: String) :*: (3.0 :: Double) :*: ()
ghci> hetlist
((1 :*: "two") :*: 3.0) :*: ()
ghci> hetlist == hetlist
True

You can imitate this using your own classes:

class DoStuff a where
  dostuff :: a -> a

instance DoStuff Int    where dostuff i = 2*i
instance DoStuff String where dostuff s = s ++ s
instance DoStuff Double where dostuff d = d / 2
instance DoStuff ()     where dostuff () = ()

instance (DoStuff a, DoStuff b) => DoStuff (a :*: b) where
  dostuff (a :*: b) = dostuff a :*: dostuff b

And then iterating over the collection happens automatically

ghci> dostuff hetlist
((2 :*: "twotwo") :*: 1.5) :*: ()

Alternatively, you can do the same using ExistentialQuantificationwrapper types, and then you will not need to define your own list type.

data DoStuffWrapper = forall a. (DoStuff a) => DoStuffWrapper a
homlist = [ DoStuffWrapper (1 :: Int)
          , DoStuffWrapper ("two" :: String)
          , DoStuffWrapper (3.0 :: Double) 
          ]
homlist' = map (\(DoStuffWrapper a) -> DoStuffWrapper (dostuff a)) homlist
+4
source

HList , - .

( , , Prolog), ( ) - , . - OverlappingInstances (? ?) .

, "- ", -; , , , , , .

(EDIT: , . Rampion , , .)

, , , HList , .

+5

Source: https://habr.com/ru/post/1792693/


All Articles