Home > Blockchain >  Union type (a -> b | IO b) in Haskell?
Union type (a -> b | IO b) in Haskell?

Time:02-08

I need to define a Union Type which the set of the type includes

a -> b OR a -> IO b

a -> b || a -> IO b

or

a -> b | IO b

foo :: (a -> b | IO b) -> IO (R a) -> IO (R b)

I tried data unionType b = b | IO b that does not work.

Not a data constructor: ‘b’parser
No quick fixes available

Is it possible in Haskell?

CodePudding user response:

In Haskell, a sum type (the standard term for a disjoint union type) requires explicit "constructors" for its components, so you need to write something like:

data BarType b = BarPure b | BarIO (IO b)

This defines a type BarType, and it also defines constructors BarPure and BarIO for use in constructing values of this type:

val1, val2 :: BarType String
val1 = BarPure "pure"
val2 = BarIO getLine

and consuming values of this type via case-matching:

runBar :: BarType b -> IO b
runBar barb = case barb of
  BarPure s -> pure s
  BarIO act -> act

CodePudding user response:

There are two issues: On the one hand your type must be upper-case, that is UnionType. Second, you need to define type constructors to be able to create a value of said data type. So the closest would be e.g.

data UnionType b = Left b | Right (IO b)

Here I chose the arbitrary names Left and Right for the constructors, but you can use any you like.

If the Left/Right constructors seem familiar to you, that is because Either uses these by default, and can do exactly the same with a slightly "cheaper" type synonym:

type UnionType b = Either b (IO b)

Of course in both cases we have to deconstruct the type to get to the actual values of b and IO b.

EDIT: As @leftroundabout mentioned, it is not very convenient to define a data type with type constructors called Left and Right, as these constructors are already used with the built in Either.

  •  Tags:  
  • Related