How to create a Haskell data structure containing polyvariadic functions? - haskell

How should I type and implement run, so that the following statements work ?
data Run = Run {run :: ??}
f1 = Run (\x -> x)
f2 = Run (\x y-> x+y)
f3 = Run (\x y z -> x*(y+z))
print $ run f1 1 :: Int --> 1
print $ run f2 1 2 :: Int --> 3
print $ run f3 1 2 3 :: Int -> 5
All the polyvariadic functions in Run are of type Int -> ... -> Int: they take a variable number of Int arguments and yield a Int.
If it's any easier, I could live with a solution having a maximum number of arguments, e.g. 3:
data Run
= Run1 (Int -> Int)
| Run2 (Int -> Int -> Int)
| Run3 (Int -> Int -> Int -> Int)
f1 = Run1 (\x -> x)
f2 = Run2 (\x y-> x+y)
f3 = Run3 (\x y z -> x*(y+z))
How would you implement run ?

Since both f1 and f2 in your code have the same type Run, the type checker can not distinguish between run f1 and run f2 which must have the same type.
This makes it hard to implement variadic functions properly.
It's much easier to use instead
data Run a = Run { run :: a }
so that f1 and f2 no longer share the same type.
If you only care about functions Int -> ... -> Int there might be some solutions using type families, GADTs, DataKinds, and the like. This may be overkill, though, depending on what you are trying to realize.

Related

Regarding evaluation order

multiply :: Int -> Int -> Int
multiply a b = a * b
minus :: Int -> Int -> Int
minus a b = a - b
minus2 :: Int -> Int -> Int
minus2 a b = b – a
minus2 (multiply (minus 3 5) 7) 9
minus2 ((minus 3 5) * 7) 9
9 - ((minus 3 5) * 7)
9 - ((3 - 5) * 7)
9 - ((-2) * 7)
9 - (-14)
23
Running the line minus2 (multiply (minus 3 5) 7) 9
Do I have the correct order of evaluation that Haskell would use?
Still new with functional programming so I'm not sure if I have the "lazy evaluation" process correct.
You can test your hypothesis by replacing subexpressions by (error "x"), (error "y"), etc. Whichever error is evaluated first is the one to show up when you run the expression.
To the point, evaluation can proceed in any order the compiler wants it to, as long as it gets the correct answer. For example, it could optimize the entire expression to 23 and have no evaluation at all at runtime. It could evaluate the right side of arithmetic operators before the left side, except for subtraction. It could randomly decide at runtime which to evaluate first.
Ignoring that, for an explanation of how to manually do the work, see "How Lazy Evaluation Works in Haskell".
But how to manually figure it out is not the main point of this answer. Your question was what evaluation order Haskell would actually use, so this answer loosely intends to tell you the evaluation order your program uses when compiled with the compiler of your choice (ignoring some caveats that don't matter for basic understanding of evaluation order).
With some work, we can have Haskell tell us what order it evaluates in. If you're in school, you probably want to learn how to find the evaluation order manually without assistance so that you can do well on a test.
It's recommended that you only do this to check an answer you're confident in. You can also use it if you get stuck, but you should only read up until the point that you're stuck to see what the next step is and to make an educated guess about why that's the next step so that you can begin to learn what the rules are by experimenting. This, in combination with the above linked article, will help quite a bit.
To do this, we can expand upon Jonas Duregård's answer by using Debug.Trace's functions instead of error. Debug.Trace's functions can output things when something starts or stops being evaluated, so they're quite appropriate here:
import Debug.Trace
-- Show result
r :: String -> Int -> Int
r nm n = trace ("Result of " ++ nm ++ " is " ++ show n) n
-- Show evaluation of Int -> Int -> Int function
f :: String -> (Int -> Int -> Int) -> Int -> Int -> Int
f nm g a b = e nm $ g a b
-- Show evaluation of an Int
e :: String -> Int -> Int
e nm = r nm . trace ("Evaluating " ++ nm)
-- Show Int literal
i :: Int -> Int
i n = e (show n) n
multiply :: Int -> Int -> Int
multiply a b = e "multiply" $ (f "multiply's *" (*))
(e "multiply's a" a)
(e "multiply's b" b)
minus :: Int -> Int -> Int
minus a b = e "minus" $ (f "minus's -" (-))
(e "minus's a" a)
(e "minus's b" b)
minus2 :: Int -> Int -> Int
minus2 a b = e "minus2" $ (f "minus2's -" (-))
(e "minus2's b" b)
(e "minus2's a" a)
main :: IO ()
main = print $ minus2 (multiply (minus (i 3) (i 5)) (i 7)) (i 9)
Once you've solved the problem on paper, you can check your answer with the results of the above code run on GHC. It tells you what evaluation order your code uses when compiled with GHC.
You can alternatively run this through the Haskell compiler of your choice.

Currying and Brackets in function calls

I have a hard time to understand Currying in Haskell. I was not able to understand the already existing answers to this topic. I want to understand what the difference is between:
(Int -> Int) -> Int
and
Int -> (Int - > Int)
I think the answer has something to do with currying. I have already consulted some resources about the topic and I have got an idea.
Functions that have several parameters can be described as an array of elementary operations with one input and one output.
According to the online tutorial learnyouahaskell:
"Doing max 4 5 first creates a function that takes a parameter and returns either 4 or that parameter, depending on which is bigger. Then, 5 is applied to that function and that function produces our desired result."
So in this case the elementary basic operations are just comparing two values. And the first operation is
if "lowest value possible" > 4 then "lowest value possible" otherwise 4
The second operation is
if 4 > 5 then 4 otherwise 5
This would represent Int -> (Int -> Int) but what would (Int -> Int) -> Int be?
Int -> (Int -> Int)
is the same type as
Int -> Int -> Int
and is the type of a curried two-arguments function, both being integers. That is it is a function which takes an integer argument and returns a function, whose argument is another integer, and which finally returns an integer.
Possible calls are f 3 2 and f (7+4) (5*8).
Possible definitions are f a b = a+b and f a b = a*a+42*b.
Instead,
(Int -> Int) - > Int
is not a binary function, curried or not. It is a function with a single argument, and this argument is a function Int -> Int. The final result is an integer.
Possible calls are f (\x -> x+1), f id, and f g where g n = n*4+5.
Possible definitions are f h = h 45 and f h = h (h 6) + h 7 + 9.
The idea of partial function application is a hallmark of Haskell.
Exploiting partial application is natural. It is much how we think.
I fill my glass half with tea. Then I fill it completely with lemonaid.
m2 = max 4 --partial application (Int -> Int)
m2 5 -- full application (Int -> Int) -> Int
All functions in Haskell are curried. It is sometimes necessary to disable it with uncurry
m3 = uncurry max
m4 = m3 4 -- does not become (Int -> Int)
m4 3 -- is not (Int -> Int) -> Int -> Int
Does not work and the error has to do with partial application (Int -> Int) because the function now requires two parameters.

Accessing self-defined Datatypes - Lambda function application order

Got this:
data Cmd = PushK Int | Pop | Push Int
deriving (Eq,Show)
type StackProgram = [Cmd]
Question:
How can I access the Int value of PushK?
> head [PushK 5, Pop]
PushK 5 -- Great!
> (\_ x -> x)PushK 5
5 -- Great!
> (\_ x -> x)(head [PushK 5, Pop])
Couldn't match expected type `t1 -> t' with actual type `Cmd'
Anyone have a solution?
You unwrap values out of a data constructor by using pattern matching, or by defining record syntax (in which case Haskell generates the getters itself).
Pattern matching
Since here the type is not defined as record, we thus have to use pattern matching:
getK :: Cmd -> Int
getK (PushK x) = x
-- ...
and probably you need to handle the cases of another data constructor.
We can also perform this pattern matching with a lambda expression:
(\(PushK x) -> x) (PushK 5)
Records
We can also define the command as a record:
data Cmd = PushK { k :: Int } | Pop | Push { p :: Int } deriving (Eq,Show)
Now Haskell has generated two functions k :: Cmd -> Int and p :: Cmd -> Int automatically, so in that case we can write:
k (PushK 5)
which will return 5.
Why did (\_ x -> x) PushK 5 return 5?
In Haskell functions are first class citizens. That means you can pass functions as arguments, return them as result. You here did not constructed a Cmd.
In fact PushK is a data constructor, and a function (with type Int -> Cmd), you thus called the lambda expression with two parameters: the first one is the pushK, and the second is 5. You simply omit the first parameter, and retun the second x.
But it is thus derived as:
(\y x -> x) PushK 5
= ((\y -> (\x -> x)) PushK) 5 -- (more verbose version)
-> (\x -> x) 5
-> 5
You may want to define a single catamorphism to deconstruct an arbitrary Cmd value.
cmdCata :: (Int -> a) -- Function to apply to x in (PushK x)
-> a -- Value to replace Pop
-> (Int -> a) -- Function to apply to x in (Push x)
-> Cmd -- The value to deconstruct
-> a -- The result
cmdCata f _ _ (PushK x) = f x
cmdCata _ x _ Pop = x
cmdCata _ _ f (Push x) = f x
It takes two functions and a default value (for Pop) to turn any Cmd value into a value of type a. The following extracts the value wrapped by PushK or Push and rewraps it with Just (the function for PushK doing a little extra work just to show the difference between PushK and Push), and replaces Pop with Nothing.
> cmdCata (Just . (+3)) Nothing Just (PushK 5)
Just 8 -- 5 + 3
> cmdCata (Just . (+3)) Nothing Just Pop
Nothing
> cmdCata (Just . (+3)) Nothing Just (Push 20)
Just 20
Or if you just want an integer and a default value for Pop is fine:
> cmdCata id 0 id (PushK 5)
5
> cmdCata id 0 id Pop
0
> cmdcata id 0 id (Push 3)
3
Compare cmdCata to Data.Maybe.maybe, and think of what functions analogous to Data.Maybe.fromJust, Data.Maybe.catMaybes, etc, could be defined for your Cmd type.

Tagging functions in Haskell

An elementary Haskell question:
I would like to "tag functions" in Haskell: I have a list
scheme = [ f1, f2, f3, ... ]
which is built from some simple functions, some of them belonging to a certain group:
f1 :: a -> a
f1 a = ...
f2 :: a -> a -- "belongs to group"
f2 a = ...
f3 :: a -> a
f3 a = ...
f4 :: a -> a -- "belongs to group"
f4 a = ...
...
I want to create a smaller list, containing only the functions belonging to that subgroup:
filter belongsToGroup scheme
In Java, the functions would be subclasses of a Function class, some of them implementing an empty tagging interface FunctionGroup. The filter function could then be realized with the operator instanceof
I tried to understand how I could mimic this behaviour in Haskell (studying "type classes"), but had no success.
Any help?
Haskell actively discourages you from using type system escape hatches. (An instanceof-like construct would break some nice type system properties such as parametricity.) You most likely want to use this type:
type TaggedFunction a b = (a -> b, Bool)
Where first component is just the regular function you want to use, and the second component is True when the function belongs to the group, or False otherwise.
Then you filter TaggedFunctions like this: filter snd tfs
One approach to this problem would be to create a data type representing these functions.
data TaggedFunction a = UsefulFunction (a -> a)
| UselessFunction (a -> a)
f1 :: TaggedFunction a
f1 = UsefulFunction $ \x -> x
f2 :: TaggedFunction a
f2 = UselessFunction $ \x -> x
isUseful :: TaggedFunction a -> Bool
isUseful (UsefulFunction _) = True
isUseful _ = False
main :: IO ()
main = do
let fs = [f1, f2, f1, f2]
useful = filter isUseful fs
print $ (_f $ head useful) 4
This method is easily expandable to include more than two groups, and could even be automatically generated with e.g. Template Haskell.
Edit
After a bit of playing around, I like this refactor of TaggedFunction better.
data TaggedFunction a = Group1 { _f :: a }
| Group2 { _f :: a }
| Group3 { _f :: a }
f1 :: TaggedFunction (a -> a)
f1 = Group1 $ \x -> x
f2 :: TaggedFunction (a -> a)
f2 = Group2 $ \x -> x
isGroup :: Int -> TaggedFunction a -> Bool
isGroup 1 (Group1 _) = True
isGroup 2 (Group2 _) = True
isGroup 3 (Group3 _) = True
isGroup _ _ = False
main :: IO ()
main = do
let fs = [f1, f2, f1, f2]
useful = filter (isGroup 1) fs
print $ length useful
print $ (_f $ head useful) 4
Output:
λ> main
2
4
Note that isGroup is now not total (which I don't like), but it was more convenient than individual isGroupN functions for the purposes of this example.

Show basic arithmetic functions as string

for a homework assignment, a subtask is to make the arithmetic functions (+), (-), (*) and div showable.
We're solved the rest of the assignment, but we're stuck here. Right now we're using the solution to this question here to distinguish between the operations:
showOp op = case op 3 3 of
6 -> "plus"
0 -> "minus"
9 -> "times"
1 -> "divide"
_ -> "undefined"
However, this strikes me as kind of ugly as things like showOp (\a b -> a * 3 - y) yield "plus".
Is there any way to better distinguish between the operators?
We are using winhugs atm with the appropriate switches -98 +o in order to be able to use the needed extensions.
Edit:
As requested, the actual assignment has to do with Arrays (specifically Array Int (Int -> Int -> Int)). It has to do with generating arrays of operators that fulfill certain conditions.
The assignment states:
Make the data type Array Int (Int->Int-Int) an Instance of Show. The arithmetic operations from the previous exercises should be represented as "plus", "minus", "times" and "div".
thx for any help in advance
Use induction :)
{-# LANGUAGE FlexibleInstances #-}
instance Eq (Int-> Int -> Int) where
f == g = induce f g where
base = 1
n = 2
induce f g = and [f 1 n' == g 1 n' | n' <- [base, n, n+1]]
instance Show (Int-> Int -> Int) where
show a = showOp a where
showOp op = case lookup op ops of
Just a -> a
otherwise -> "undefined"
ops = [((+),"plus")
,((-),"minus")
,((*),"times")
,(div,"divide")]
Output:
*Main> (\a b -> a * 3 - b) :: (Int->Int->Int)
undefined

Resources