Calling function in haskell - haskell

I'm pretty new in Haskell programming. I want to call some functions and save the result in a variable but I don't know how. I read couple of chapters about haskell function in two different book but still don't understand how to do it.
import Data.Map (Map)
import qualified Data.Map as M hiding (Map)
newtype GenEnv elt = Env (Map Id elt)
newEnv :: GenEnv elt -- initialise
newEnv = Env M.empty
newtype GenEnv elt = Env (Map Id elt)
newEnv :: GenEnv elt -- initialise
newEnv = Env M.empty
getEnv :: GenEnv elt -> Id -> Maybe elt -- G(x) (key function)
getEnv (Env env) var = M.lookup var env
union :: GenEnv elt -> (Id,elt) -> GenEnv elt -- G[x:v]
union (Env env) (key,elt) = Env (M.insert key elt env)
-- foldr is faster than addToFM_list!
unionL :: GenEnv elt -> [(Id,elt)] -> GenEnv elt -- list union
unionL (Env env) pairs = Env $ foldr (\(k,e) g -> M.insert k e g) env pairs
What I'm asking here is NOT for somebody to do my work, asking how to call the functions because I don't understand their signature.

As others have mentioned, "variable" is perhaps not the right term. And in the same vein, "calling" a function is perhaps not the right term either. It is helpful, in my opinion, to think about this in terms of mathematical functions:
f(x) = x^2
given the above function, you don't "call" it with a value so much as give a name to the result of evaluating that function at a particular argument:
y = f(2)
It's the same in Haskell. Somewhere in your code you need to use the result of evaluating a function at a particular value. To do that, you can just use the application of that function to that value wherever you need it, or you can bind it to a name in a let binding or a where clause.
So, to provide a simple example in Haskell, you can do something like this:
f :: Int -> Int
f x = x^2
y :: Int
y = f 2
g :: Int -> Int
g x = let y = f 3
in y + 1
h :: Int -> Int
h x = y + 1
where y = f 3
Here I have declared a function called f which takes a single Int value and returns a new Int value, the square of the argument. Then I have declared an Int value named y to be the result of applying f to 2. The value y is not a variable, but rather a binding. It will always be 4.
Then I have declared two other functions, g and h which are equivalent, showing local bindings of the results of applying f.
In your example, the types are perhaps complicating things a little bit. Env is a constructor used to construct a value of the Genenv type. So, to create a value that is a Genenv type, you apply Env to an appropriate argument. This is what newEnv is doing.
Hopefully that's enough to get you started.

Since I pretty much suck at explaining these things, I'd recomment reading this chapter
http://book.realworldhaskell.org/read/types-and-functions.html
should cover everything you need to know to be able to call those functions.
In general in Haskell we apply a function to some arguments and bind the results to some value.

Haskell doesn't have variables, first of all. Generally we talk of binding an expression to an identifier, creating a thunk.
It has the form of
let val = unionEl g l
in --expression using val

In Haskell, function application is done through juxtaposition, but you can use parentheses first to get the feel for it, just don't use commas to separate parameters like you may be used to in other languages.
For instance, assuming Id is just a type synonym for Int, then the following would be an example GenEnv.
example :: GenEnv Char
example = union newEnv (1, 'a')
which is the same as
example :: GenEnv Char
example = union(newEnv (1, 'a'))
Say you have a list of the alphabet, associated with an integer value, called alphabetKeys, you can use the handy little tool you defined to turn that into a GenEnv pretty easily, just by
example :: GenEnv Char
example = union newEnv alphabetKeys
again,
example :: GenEnv Char
example = union(newEnv alphabetKeys)
would work just as well.

Related

How and when to use State functor and State applicative?

I've seen the Maybe and Either functor (and applicative) used in code and that made sense, but I have a hard time coming up with an example of the State functor and applicative. Maybe they are not very useful and only exist because the State monad requires a functor and an applicative? There are plenty of explanations of their implementations out there but not any examples when they are used in code, so I'm looking for illustrations of how they might be useful on their own.
I can think of a couple of examples off the top of my head.
First, one common use for State is to manage a counter for the purpose of making some set of "identifiers" unique. So, the state itself is an Int, and the main primitive state operation is to retrieve the current value of the counter and increment it:
-- the state
type S = Int
newInt :: State S Int
newInt = state (\s -> (s, s+1))
The functor instance is then a succinct way of using the same counter for different types of identifiers, such as term- and type-level variables in some language:
type Prefix = String
data Var = Var Prefix Int
data TypeVar = TypeVar Prefix Int
where you generate fresh identifiers like so:
newVar :: Prefix -> State S Var
newVar s = Var s <$> newInt
newTypeVar :: Prefix -> State S TypeVar
newTypeVar s = TypeVar s <$> newInt
The applicative instance is helpful for writing expressions constructed from such unique identifiers. For example, I've used this approach pretty frequently when writing type checkers, which will often construct types with fresh variables, like so:
typeCheckAFunction = ...
let freshFunctionType = ArrowType <$> newTypeVar <*> newTypeVar
...
Here, freshFunctionType is a new a -> b style type with fresh type variables a and b that can be passed along to a unification step.
Second, another use of State is to manage a seed for random number generation. For example, if you want a low-quality but ultra-fast LCG generator for something, you can write:
lcg :: Word32 -> Word32
lcg x = (a * x + c)
where a = 1664525
c = 1013904223
-- monad for random numbers
type L = State Word32
randWord32 :: L Word32
randWord32 = state $ \s -> let s' = lcg s in (s', s')
The functor instance can be used to modify the Word32 output using a pure conversion function:
randUniform :: L Double
randUniform = toUnit <$> randWord32
where toUnit w = fromIntegral w / fromIntegral (maxBound `asTypeOf` w)
while the applicative instance can be used to write primitives that depend on multiple Word32 outputs:
randUniform2 :: L (Double, Double)
randUniform2 = (,) <$> randUniform <*> randUniform
and expressions that use your random numbers in a reasonably natural way:
-- area of a random triangle, say
a = areaOf <$> (Triangle <$> randUniform2 <*> randUniform2 <$> randUniform2)

Getting all function arguments in haskel as list

Is there a way in haskell to get all function arguments as a list.
Let's supose we have the following program, where we want to add the two smaller numbers and then subtract the largest. Suppose, we can't change the function definition of foo :: Int -> Int -> Int -> Int. Is there a way to get all function arguments as a list, other than constructing a new list and add all arguments as an element of said list? More importantly, is there a general way of doing this independent of the number of arguments?
Example:
module Foo where
import Data.List
foo :: Int -> Int -> Int -> Int
foo a b c = result!!0 + result!!1 - result!!2 where result = sort ([a, b, c])
is there a general way of doing this independent of the number of arguments?
Not really; at least it's not worth it. First off, this entire idea isn't very useful because lists are homogeneous: all elements must have the same type, so it only works for the rather unusual special case of functions which only take arguments of a single type.
Even then, the problem is that “number of arguments” isn't really a sensible concept in Haskell, because as Willem Van Onsem commented, all functions really only have one argument (further arguments are actually only given to the result of the first application, which has again function type).
That said, at least for a single argument- and final-result type, it is quite easy to pack any number of arguments into a list:
{-# LANGUAGE FlexibleInstances #-}
class UsingList f where
usingList :: ([Int] -> Int) -> f
instance UsingList Int where
usingList f = f []
instance UsingList r => UsingList (Int -> r) where
usingList f a = usingList (f . (a:))
foo :: Int -> Int -> Int -> Int
foo = usingList $ (\[α,β,γ] -> α + β - γ) . sort
It's also possible to make this work for any type of the arguments, using type families or a multi-param type class. What's not so simple though is to write it once and for all with variable type of the final result. The reason being, that would also have to handle a function as the type of final result. But then, that could also be intepreted as “we still need to add one more argument to the list”!
With all respect, I would disagree with #leftaroundabout's answer above. Something being
unusual is not a reason to shun it as unworthy.
It is correct that you would not be able to define a polymorphic variadic list constructor
without type annotations. However, we're not usually dealing with Haskell 98, where type
annotations were never required. With Dependent Haskell just around the corner, some
familiarity with non-trivial type annotations is becoming vital.
So, let's take a shot at this, disregarding worthiness considerations.
One way to define a function that does not seem to admit a single type is to make it a method of a
suitably constructed class. Many a trick involving type classes were devised by cunning
Haskellers, starting at least as early as 15 years ago. Even if we don't understand their
type wizardry in all its depth, we may still try our hand with a similar approach.
Let us first try to obtain a method for summing any number of Integers. That means repeatedly
applying a function like (+), with a uniform type such as a -> a -> a. Here's one way to do
it:
class Eval a where
eval :: Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval i = \y -> eval (i + y)
instance Eval Integer where
eval i = i
And this is the extract from repl:
λ eval 1 2 3 :: Integer
6
Notice that we can't do without explicit type annotation, because the very idea of our approach is
that an expression eval x1 ... xn may either be a function that waits for yet another argument,
or a final value.
One generalization now is to actually make a list of values. The science tells us that
we may derive any monoid from a list. Indeed, insofar as sum is a monoid, we may turn arguments to
a list, then sum it and obtain the same result as above.
Here's how we can go about turning arguments of our method to a list:
class Eval a where
eval2 :: [Integer] -> Integer -> a
instance (Eval a) => Eval (Integer -> a) where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [Integer] where
eval2 is i = i:is
This is how it would work:
λ eval2 [] 1 2 3 4 5 :: [Integer]
[5,4,3,2,1]
Unfortunately, we have to make eval binary, rather than unary, because it now has to compose two
different things: a (possibly empty) list of values and the next value to put in. Notice how it's
similar to the usual foldr:
λ foldr (:) [] [1,2,3,4,5]
[1,2,3,4,5]
The next generalization we'd like to have is allowing arbitrary types inside the list. It's a bit
tricky, as we have to make Eval a 2-parameter type class:
class Eval a i where
eval2 :: [i] -> i -> a
instance (Eval a i) => Eval (i -> a) i where
eval2 is i = \j -> eval2 (i:is) j
instance Eval [i] i where
eval2 is i = i:is
It works as the previous with Integers, but it can also carry any other type, even a function:
(I'm sorry for the messy example. I had to show a function somehow.)
λ ($ 10) <$> (eval2 [] (+1) (subtract 2) (*3) (^4) :: [Integer -> Integer])
[10000,30,8,11]
So far so good: we can convert any number of arguments into a list. However, it will be hard to
compose this function with the one that would do useful work with the resulting list, because
composition only admits unary functions − with some trickery, binary ones, but in no way the
variadic. Seems like we'll have to define our own way to compose functions. That's how I see it:
class Ap a i r where
apply :: ([i] -> r) -> [i] -> i -> a
apply', ($...) :: ([i] -> r) -> i -> a
($...) = apply'
instance Ap a i r => Ap (i -> a) i r where
apply f xs x = \y -> apply f (x:xs) y
apply' f x = \y -> apply f [x] y
instance Ap r i r where
apply f xs x = f $ x:xs
apply' f x = f [x]
Now we can write our desired function as an application of a list-admitting function to any number
of arguments:
foo' :: (Num r, Ord r, Ap a r r) => r -> a
foo' = (g $...)
where f = (\result -> (result !! 0) + (result !! 1) - (result !! 2))
g = f . sort
You'll still have to type annotate it at every call site, like this:
λ foo' 4 5 10 :: Integer
-1
− But so far, that's the best I can do.
The more I study Haskell, the more I am certain that nothing is impossible.

Typed abstract syntax and DSL design in Haskell

I'm designing a DSL in Haskell and I would like to have an assignment operation. Something like this (the code below is just for explaining my problem in a limited context, I didn't have type checked Stmt type):
data Stmt = forall a . Assign String (Exp a) -- Assignment operation
| forall a. Decl String a -- Variable declaration
data Exp t where
EBool :: Bool -> Exp Bool
EInt :: Int -> Exp Int
EAdd :: Exp Int -> Exp Int -> Exp Int
ENot :: Exp Bool -> Exp Bool
In the previous code, I'm able to use a GADT to enforce type constraints on expressions. My problem is how can I enforce that the left hand side of an assignment is: 1) Defined, i.e., a variable must be declared before it is used and 2) The right hand side must have the same type of the left hand side variable?
I know that in a full dependently typed language, I could define statements indexed by some sort of typing context, that is, a list of defined variables and their type. I believe that this would solve my problem. But, I'm wondering if there is some way to achieve this in Haskell.
Any pointer to example code or articles is highly appreciated.
Given that my work focuses on related issues of scope and type safety being encoded at the type-level, I stumbled upon this old-ish question whilst googling around and thought I'd give it a try.
This post provides, I think, an answer quite close to the original specification. The whole thing is surprisingly short once you have the right setup.
First, I'll start with a sample program to give you an idea of what the end result looks like:
program :: Program
program = Program
$ Declare (Var :: Name "foo") (Of :: Type Int)
:> Assign (The (Var :: Name "foo")) (EInt 1)
:> Declare (Var :: Name "bar") (Of :: Type Bool)
:> increment (The (Var :: Name "foo"))
:> Assign (The (Var :: Name "bar")) (ENot $ EBool True)
:> Done
Scoping
In order to ensure that we may only assign values to variables which have been declared before, we need a notion of scope.
GHC.TypeLits provides us with type-level strings (called Symbol) so we can very-well use strings as variable names if we want. And because we want to ensure type safety, each variable declaration comes with a type annotation which we will store together with the variable name. Our type of scopes is therefore: [(Symbol, *)].
We can use a type family to test whether a given Symbol is in scope and return its associated type if that is the case:
type family HasSymbol (g :: [(Symbol,*)]) (s :: Symbol) :: Maybe * where
HasSymbol '[] s = 'Nothing
HasSymbol ('(s, a) ': g) s = 'Just a
HasSymbol ('(t, a) ': g) s = HasSymbol g s
From this definition we can define a notion of variable: a variable of type a in scope g is a symbol s such that HasSymbol g s returns 'Just a. This is what the ScopedSymbol data type represents by using an existential quantification to store the s.
data ScopedSymbol (g :: [(Symbol,*)]) (a :: *) = forall s.
(HasSymbol g s ~ 'Just a) => The (Name s)
data Name (s :: Symbol) = Var
Here I am purposefully abusing notations all over the place: The is the constructor for the type ScopedSymbol and Name is a Proxy type with a nicer name and constructor. This allows us to write such niceties as:
example :: ScopedSymbol ('("foo", Int) ': '("bar", Bool) ': '[]) Bool
example = The (Var :: Name "bar")
Statements
Now that we have a notion of scope and of well-typed variables in that scope, we can start considering the effects Statements should have. Given that new variables can be declared in a Statement, we need to find a way to propagate this information in the scope. The key hindsight is to have two indices: an input and an output scope.
To Declare a new variable together with its type will expand the current scope with the pair of the variable name and the corresponding type.
Assignments on the other hand do not modify the scope. They merely associate a ScopedSymbol to an expression of the corresponding type.
data Statement (g :: [(Symbol, *)]) (h :: [(Symbol,*)]) where
Declare :: Name s -> Type a -> Statement g ('(s, a) ': g)
Assign :: ScopedSymbol g a -> Exp g a -> Statement g g
data Type (a :: *) = Of
Once again we have introduced a proxy type to have a nicer user-level syntax.
example' :: Statement '[] ('("foo", Int) ': '[])
example' = Declare (Var :: Name "foo") (Of :: Type Int)
example'' :: Statement ('("foo", Int) ': '[]) ('("foo", Int) ': '[])
example'' = Assign (The (Var :: Name "foo")) (EInt 1)
Statements can be chained in a scope-preserving way by defining the following GADT of type-aligned sequences:
infixr 5 :>
data Statements (g :: [(Symbol, *)]) (h :: [(Symbol,*)]) where
Done :: Statements g g
(:>) :: Statement g h -> Statements h i -> Statements g i
Expressions
Expressions are mostly unchanged from your original definition except that they are now scoped and a new constructor EVar lets us dereference a previously-declared variable (using ScopedSymbol) giving us an expression of the appropriate type.
data Exp (g :: [(Symbol,*)]) (t :: *) where
EVar :: ScopedSymbol g a -> Exp g a
EBool :: Bool -> Exp g Bool
EInt :: Int -> Exp g Int
EAdd :: Exp g Int -> Exp g Int -> Exp g Int
ENot :: Exp g Bool -> Exp g Bool
Programs
A Program is quite simply a sequence of statements starting in the empty scope. We use, once more, an existential quantification to hide the scope we end up with.
data Program = forall h. Program (Statements '[] h)
It is obviously possible to write subroutines in Haskell and use them in your programs. In the example, I have the very simple increment which can be defined like so:
increment :: ScopedSymbol g Int -> Statement g g
increment v = Assign v (EAdd (EVar v) (EInt 1))
I have uploaded the whole code snippet together with the right LANGUAGE pragmas and the examples listed here in a self-contained gist. I haven't however included any comments there.
You should know that your goals are quite lofty. I don't think you will get very far treating your variables exactly as strings. I'd do something slightly more annoying to use, but more practical. Define a monad for your DSL, which I'll call M:
newtype M a = ...
data Exp a where
... as before ...
data Var a -- a typed variable
assign :: Var a -> Exp a -> M ()
declare :: String -> a -> M (Var a)
I'm not sure why you have Exp a for assignment and just a for declaration, but I reproduced that here. The String in declare is just for cosmetics, if you need it for code generation or error reporting or something -- the identity of the variable should really not be tied to that name. So it's usually used as
myFunc = do
foobar <- declare "foobar" 42
which is the annoying redundant bit. Haskell doesn't really have a good way around this (though depending on what you're doing with your DSL, you may not need the string at all).
As for the implementation, maybe something like
data Stmt = forall a. Assign (Var a) (Exp a)
| forall a. Declare (Var a) a
data Var a = Var String Integer -- string is auxiliary from before, integer
-- stores real identity.
For M, we need a unique supply of names and a list of statements to output.
newtype M a = M { runM :: WriterT [Stmt] (StateT Integer Identity a) }
deriving (Functor, Applicative, Monad)
Then the operations as usually fairly trivial.
assign v a = M $ tell [Assign v a]
declare name a = M $ do
ident <- lift get
lift . put $! ident + 1
let var = Var name ident
tell [Declare var a]
return var
I've made a fairly large DSL for code generation in another language using a fairly similar design, and it scales well. I find it a good idea to stay "near the ground", just doing solid modeling without using too many fancy type-level magical features, and accepting minor linguistic annoyances. That way Haskell's main strength -- it's ability to abstract -- can still be used for code in your DSL.
One drawback is that everything needs to be defined within a do block, which can be a hinderance to good organization as the amount of code grows. I'll steal declare to show a way around that:
declare :: String -> M a -> M a
used like
foo = declare "foo" $ do
-- actual function body
then your M can have as a component of its state a cache from names to variables, and the first time you use a declaration with a certain name you render it and put it in a variable (this will require a bit more sophisticated monoid than [Stmt] as the target of your Writer). Later times you just look up the variable. It does have a rather floppy dependence on uniqueness of names, unfortunately; an explicit model of namespaces can help with that but never eliminate it entirely.
After seeing all the code by #Cactus and the Haskell suggestions by #luqui, I've managed to got a solution close to what I want in Idris. The complete code is available at the following gist:
(https://gist.github.com/rodrigogribeiro/33356c62e36bff54831d)
Some little things I need to fix in the previous solution:
I don't know (yet) if Idris support integer literal overloading, what would be quite useful to build my DSL.
I've tried to define in DSL syntax a prefix operator for program variables, but it didn't worked as I like. I've got a solution (in the previous gist) that uses a keyword --- use --- for variable access.
I'll check this minor points with guys in Idris #freenode channel to see if these two points are possible.

Counting occurrences in an expression

I'm pretty new to Haskell and I have an assessment which involves a manipulator and evaluator of boolean expressions.
Thee expression type is:
type Variable = String
data Expr = T | Var Variable | And Expr Expr | Not Expr
I've worked through a lot of the questions but i am stuck on how to approach the following function. I need to count the occurences of all the variables in an expression
addCounter :: Expr -> Expr
addCounter = undefined
prop_addCounter1 = addCounter (And (Var "y") (And (Var "x") (Var "y"))) ==
And (Var "y1") (And (Var "x2") (Var "y1"))
prop_addCounter2 = addCounter (Not (And (Var "y") T)) ==
Not (And (Var "y1") T)
I'm not looking for an answer on exactly how to do this as it is an assessment question but I would like some tips on how I would go about approaching this?
In my head I imagine incrementing a counter so that I can get the y1, x2 part but this isn't really something that is possible in Haskell (or not advised to do anyway!) Would I go about this through recursion and if so how do I know what number to add to the variable?
As you say you cannot keep a shared counter which would be very natural in this case. What you can do instead is to pass the current counter value down the tree as you recursively visit all Expr's, and receive back the incremented counter value from the function being called. It must be a two-way communication. You pass down the current value and receive back the updated Expr and the new counter value.
If you want each unique variable name to have the same counter value you need to keep a mapping of variable names to assigned counter values. You need to pass that one around just like the current counter value.
Hope that helps.
Atomize your stateful updates
So, this is definitely a great time to use a State monad. In particular, the atomic transform you're looking for is a way to take String -> String enumerating strings by a unique id for each string. Let's call it enumerate
import Control.Monad.State
-- | This is the only function which is going to touch our 'Variable's
enumerate :: Variable -> State OurState Variable
To do this, we'll need to track state that maps Strings to counts (Ints)
import qualified Data.Map as M
type OurState = Map String Int
runOurState :: State OurState a -> a
runOurState = flip evalState M.empty
runOurState $ mapM enumerate ["x", "y", "z", "x" ,"x", "x", "y"]
-- ["x1", "y1", "z1", "x2", "x3", "x4", "y2"]
so we can implement enumerate pretty directly as a stateful action.
enumerate :: Variable -> State OurState Variable
enumerate var = do m <- get
let n = 1 + M.findWithDefault 0 var m
put $ M.insert var n m
return $ var ++ show n
Cool!
Folding generically over an expression tree
Now we really ought to write an elaborate folding apparatus which maps Expr -> State OurState Expr by applying enumerate on each Var-type leaf.
enumerateExpr :: Expr -> State OurState Expr
enumerateExpr T = return T
enumerateExpr (Var s) = fmap Var (enumerate s)
enumerateExpr (And e1 e2) = do em1 <- addCounter e1
em2 <- addCounter e2
return (Add em1 em2)
enumerateExpr (Not expr) = fmap Not (addCounter expr)
But this is pretty tedious, so we'll use the Uniplate library to keep dry.
{-# LANGUAGE DeriveDataTypeable #-}
import Data.Data
import Data.Generics.Uniplate.Data
data Expr = T | Var Variable | And Expr Expr | Not Expr
deriving (Show,Eq,Ord,Data)
onVarStringM :: (Variable -> State OurState Variable) -> Expr -> State OurState Expr
onVarStringM action = transformM go
where go :: Expr -> State OurState Expr
go (Var s) = fmap Var (action s)
go x = return x
The transformM operator does just what we want—apply a monadic transformation over all the pieces of a generic tree (our Expr).
So now, we just unpack the Stateful action to make addCounter
addCounter :: Expr -> Expr
addCounter = runOurState . onVarStringM enumerate
Oh, wait!
Just noticed, this doesn't actually have the right behavior—it doesn't enumerate your variables quite right (prop_addCounter1 fails but prop_addCounter2 passes). Unfortunately, I'm not really sure how it ought to be done... but given this separation of concerns laid out here it'd be very easy to just write the appropriate enumerate Stateful action and apply it to the same generic Expr-transforming machinery.

What type signature do I need to allow a list of functions to be converted to haskell code? [duplicate]

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
Why is such a function definition not allowed in haskell?
I made a haskell function called funlist. What it does is it takes a starting value, and a list of functions, and applies all of the functions in the list to the starting value.
funlist thing [function] = function thing
funlist thing (function:functions) = funlist (function thing) functions
funlist _ _ = error "need a list of functions"
The problem with this function is that it has a type of funlist :: t -> [t -> t] -> t. That type means that while ghc will allow a list of functions that don't convert the starting value to a completely different type (e.g [sin,cos,tan] will be allowed), a function that converts the starting value to a different type (e.g show) will generate an error because that function doesn't match the type signature.
This isn't how the function should work. It should be able to take a list of functions that change the starting values type (e.g. [sin,show]). This function basically converts funlist 5 [sin,cos,tan,isInfinite,show] to show $ isInfinite $ tan $ cos $ sin $ 5, and while the latter works, the former doesn't.
Is there any way that I can get this function to work properly?
EDIT: I know about . and >>>, I'm just wondering if there's a way to make this work.
You can write what you want with a GADT:
{-# LANGUAGE GADTs #-}
module Funlist where
data F x y where
Id :: F a a
Ap :: (a->b) -> F b c -> F a c
-- A very round about way to write f x = x + x
f1 :: Int -> Char
f1 = toEnum
f2 :: Char -> String
f2 x = x:x:[]
f3 :: String -> [Int]
f3 = map fromEnum
f4 :: [Int] -> Integer
f4 = foldr (+) 0 . map toInteger
f_list :: F Int Integer
f_list = Ap f1 (Ap f2 (Ap f3 (Ap f4 Id)))
ap :: F a b -> a -> b
ap Id x = x
ap (Ap f gs) x = ap gs (f x)
Now ap f_list 65 is 130
This does not work with normal functions/normal lists in Haskell, since it requires a dynamically typed language, and not a statically typed language like Haskell. The funlist function can't have a different type depending on what the contents of the function list is at runtime; its type must be known at compile-time. Further, the compiler must be able to check that the function chain is valid, so that you can't use the list [tan, show, sin] for example.
There are two solutions to this problem.
You can either use heterogenous lists. These lists can store lists where each element is a different type. You can then check the constraint that each element must be a function and that one elements return type must be the next function's parameter type. This can become very difficult very quickly.
You can also use Data.Dynamic to let your functions take and return dynamic types. You have to perform some dynamic type casts in that case.
If all you're going to do with this list of functions is apply them to a single value in a pipeline, then instead of writing and calling your funlist function, do this:
show . isInfinite . tan . cos . sin $ 5
or, if you don't want the list reversed in your code, do this:
import Control.Arrow (>>>)
(sin >>> cos >>> tan >>> isInfinite >>> show) 5
Functions in Haskell, in general, have types that look like a -> b, for some choice of a and b. In your case, you have a list [f0, ..., fn] of functions, and you want to compute this:
funlist [f0, ..., fn] x == f0 (funlist [f1, ..., fn] x)
== f0 (f1 (funlist [f2, ..., fn] x))
...
== f0 (f1 (... (fn x)))
The t -> t problem you're having is a consequence of these two things:
This computation requires the argument type of f0 to be the return type of f1, the argument type of f1 to be the return type of f2, and so on: f0 :: y -> z, f1 :: x -> y, ..., fn :: a -> b.
But you're putting all those functions in a list, and all the elements of a list in Haskell must have the same type.
These two, taken together, imply that the list of functions used in funlist must have type [t -> t], because that's the only way both conditions can be met at the same time.
Other than that, dave4420's answer is the best simple answer, IMO: use function composition. If you can't use it because the computation to be done is only known at runtime, then you want to have some data structure more complex than the list to represent the possible computations. Chris Kuklewicz presents a very generic solution for that, but I'd normally do something custom-made for the specific problem area at hand.
Also good to know that your funlist can be written like this:
funlist :: a -> [a -> a] -> a
funlist x fs = foldr (.) id fs x
Short answer: No, there's no way to do what you want with lists (in a sensible way, at least).
The reason is that lists in Haskell are always homogenous, i.e. each element of a list must have the same type. The functions you want to put to the list have types:
sin :: Floating a => a -> a
isInfinite :: Floating b => b -> Bool
show :: Show c => c -> String
So you can't just put the functions in the same list. Your two main options are to:
Use a structure other than list (e.g. HList or a custom GADT)
Use dynamic typing
Since the other answers already gave GADT examples, here's how you could implement your function using dynamic types:
import Data.Dynamic
funlist :: Dynamic -> [Dynamic] -> Dynamic
funlist thing (function:functions) = funlist (dynApp function thing) functions
funlist thing [] = thing
However, using dynamic types causes some boilerplate, because you have to convert between static and dynamic types. So, to call the function, you'd need to write
funlist (toDyn 5) [toDyn sin, toDyn cos, toDyn tan, toDyn isInfinite, toDyn show]
And unfortunately, even that is not enough. The next problem is that dynamic values must have homomorphic types, so for example instead of the function show :: Show a => a -> String you need to manually specify e.g. the concrete type show :: Bool -> String, so the above becomes:
funlist (toDyn (5::Double)) [toDyn sin, toDyn cos, toDyn tan, toDyn isInfinite,
toDyn (show :: Bool -> String)]
What's more, the result of the function is another dynamic value, so we need to convert it back to a static value if we want to use it in regular functions.
fromDyn (funlist (toDyn (5::Double)) [toDyn sin, toDyn cos, toDyn tan,
toDyn isInfinite, toDyn (show :: Bool -> String)]) ""
What you want works in Haskell, but it's not a list. It is a function composition and can actually be wrapped in a GADT:
import Control.Arrow
import Control.Category
import Prelude hiding ((.), id)
data Chain :: * -> * -> * where
Chain :: (a -> c) -> Chain c b -> Chain a b
Id :: Chain a a
apply :: Chain a b -> a -> b
apply (Chain f k) x = apply k (f x)
apply Id x = x
Now you can inspect the structure of the function chain to some extent. There isn't much you can find out, but you can add further meta information to the Chain constructor, if you need more.
The type also forms an interesting category that preserves the additional information:
instance Category Chain where
id = Id
Id . c = c
c . Id = c
c2 . Chain f1 k1 = Chain f1 (c2 . k1)
instance Arrow Chain where
arr f = Chain f Id
first (Chain f c) = Chain (first f) (first c)
first Id = Id
There where some answers using GADTs, which is a good way to do such things. What I want to add here is that the structure used in these answers already exists in a more general fashion: it's called a thrist ("type threaded list"):
Prelude Data.Thrist> let fs = Cons (show :: Char -> String) (Cons length Nil)
Prelude Data.Thrist> let f = foldl1Thrist (flip (.)) fs
Prelude Data.Thrist> :t fs
fs :: Thrist (->) Char Int
Prelude Data.Thrist> :t f
f :: Char -> Int
Prelude Data.Thrist> f 'a'
3
Of course, you could also use foldl1Thrist (>>>) fs instead. Note that thrists form a category, an arrow and a monoid (with appendThrist).

Resources