Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Pass Types as arguments to a function in Haskell?

Tags:

types

haskell

The following two functions are extremely similar. They read from a [String] n elements, either [Int] or [Float]. How can I factor the common code out? I don't know of any mechanism in Haskell that supports passing types as arguments.

readInts n stream = foldl next ([], stream) [1..n]
  where
    next (lst, x:xs) _ = (lst ++ [v], xs)
      where
        v = read x :: Int

readFloats n stream = foldl next ([], stream) [1..n]
  where
    next (lst, x:xs) _ = (lst ++ [v], xs)
      where
        v = read x :: Float

I am at a beginner level of Haskell, so any comments on my code are welcome.

like image 732
Chang Peng Avatar asked Apr 06 '12 04:04

Chang Peng


People also ask

What is type declaration in Haskell?

Haskell has three basic ways to declare a new type: The data declaration, which defines new data types. The type declaration for type synonyms, that is, alternative names for existing types. The newtype declaration, which defines new data types equivalent to existing ones.

What does == mean in Haskell?

The == is an operator for comparing if two things are equal. It is quite normal haskell function with type "Eq a => a -> a -> Bool". The type tells that it works on every type of a value that implements Eq typeclass, so it is kind of overloaded.

Does every Haskell function have a type?

Everything in Haskell has a type, so the compiler can reason quite a lot about your program before compiling it. Unlike Java or Pascal, Haskell has type inference.


1 Answers

Haskell supports a high degree of polymorphism. In particular

readAny n stream = foldl next ([], stream) [1..n]
  where
    next (lst, x:xs) _ = (lst ++ [v], xs)
      where
        v = read x 

has type

readAny :: (Enum b, Num b, Read a) => b -> [String] -> ([a], [String])

thus

readInts :: (Enum b, Num b) => b -> [String] -> ([Int], [String])
readInts = readAny

readFloats :: (Enum b, Num b) => b -> [String] -> ([Float], [String])
readFloats = readAny

you dont need to specialize the type. Haskell will automatically infer the most general type possible, and the readAny here will do what you want.

It is not possible to pass types as arguments in Haskell. Rarely would you need to. For those few cases where it is necessary you can simulate the behavior by passing a value with the desired type.

Haskell has "return type polymorphism" so you really shouldn't worry about "passing the type"--odds are that functions will do what you want without you telling them to.

like image 84
Philip JF Avatar answered Sep 19 '22 19:09

Philip JF