user defined higher order functions in haskell - haskell

i went though several Haskell learning examples but i could not figure out how to write user defined higher order functions in Haskell
if we are taking a parameter as a function how the type of the function id defined?

Let's use the function map as a simple example. map takes a function and a list and applies the function to all elements of the list. If you write the signature of map, it runs like this:
First, you need a function. Any function is OK, so the type of the first argument is a -> b. Then, you need a list of input values. Since the type of the list's elements must fit to the function's input, the type of the list is [a]. For the output: What is the result of a function a -> b when applied to a value of type a? Right, it is b. So the result type is [b]. Assembled together, the type of our function runs like this:
map :: (a -> b) -> [a] -> [b]
And is defined like this:
map f [] = []
map f (x:xs) = f x : map f xs
Does this help you to understand the concept of high order functions?

Don't concern yourself with types just yet. Ask the compiler, it will tell you the types. With some practice you will be able to see the types almost as well as the compiler [grin].
Here we define two very simple higher-order functions, twice and compose. The first one takes a function and an argument, and applies one to the other, twice. The second one takes two functions and an argument and applies both functions to it in chain.
$ ghci
GHCi, version 6.12.1: http://www.haskell.org/ghc/ :? for help
Loading package ghc-prim ... linking ... done.
Loading package integer-gmp ... linking ... done.
Loading package base ... linking ... done.
Prelude> let twice f x = f (f x)
Prelude> :t twice
twice :: (t -> t) -> t -> t
Prelude> let compose f g x = f (g x)
Prelude> :t compose
compose :: (t1 -> t2) -> (t -> t1) -> t -> t2
Prelude>
You can see that twice gets two arguments, of type (t->t) an of type t, and returns a resulkt of type t. t is any type (but the same in all 4 occurrences).
You can try to use these higher-order functions on some regular functions.
Prelude> let times3 x = x * 3
Prelude> let times5 x = x * 5
Prelude> twice times3 2
18
Prelude> twice times5 2
50
Prelude> compose times3 times5 2
30
Prelude>
Ans some funky advanced stuff:
Prelude> (twice twice) times3 2
162
Prelude> twice (twice times3) 2
162
Prelude>
Do you understand what's going on in the last two examples?

Related

Variadic list appender function to make a list of lists from lists in haskell

I'm looking at this question for how to take multiple lists and turn them into a list of lists. I have the following:
Prelude> x1 = [1,2,3]
Prelude> x2 = [4,5,6]
Prelude> x3 = [7,8,9]
I'd like to see some \function where this could be variadic:
Prelude> xs = map (\function -> ???) x1 x2 x3
Prelude> show xs -- that produces this
[[1,2,3], [4,5,6], [7,8,9]]
Or without map, some other variadic function F such that:
Prelude> xs = F x1 x2 x3 ... x1000
Prelude> show xs -- that produces this
[[1,2,3], [4,5,6], [7,8,9], ...., [1000000,1000001,1000002]]
My expectation from the answer was that something like
Prelude> map (:) x1 x2 x3 []
<interactive>:26:1: error:
• Couldn't match expected type ‘[Integer]
-> [Integer] -> [a0] -> t’
with actual type ‘[[Integer] -> [Integer]]’
• The function ‘map’ is applied to five arguments,
but its type ‘(Integer -> [Integer] -> [Integer])
-> [Integer] -> [[Integer] -> [Integer]]’
has only two
In the expression: map (:) x1 x2 x3 []
In an equation for ‘it’: it = map (:) x1 x2 x3 []
• Relevant bindings include it :: t (bound at <interactive>:26:1)
or
Prelude> map (:) $ x1 x2 x3 []
<interactive>:27:11: error:
• Couldn't match expected type ‘[Integer]
-> [Integer] -> [a0] -> [a]’
with actual type ‘[Integer]’
• The function ‘x1’ is applied to three arguments,
but its type ‘[Integer]’ has none
In the second argument of ‘($)’, namely ‘x1 x2 x3 []’
In the expression: map (:) $ x1 x2 x3 []
• Relevant bindings include
it :: [[a] -> [a]] (bound at <interactive>:27:1)
I failed to find this kind of function in Hoogle as well, but probably misspecified the type signature:
https://www.haskell.org/hoogle/?hoogle=%5Ba%5D+-%3E+%5Ba%5D+-%3E+%5B%5Ba%5D%2C%5Ba%5D%5D
Polyvariadic functions in Haskell are quite hard to achieve. This is because a function can fundamentally only have one argument, and hence further arguments are included only through currying, which bakes the number of arguments into the function's type.
However, that doesn't mean it's impossible, though sometimes this requires the use of extensions. Here I will go through a few, in increasing order of complexity. This probably won't be very useful, but maybe helpful.
Somewhat tangentially, a few years ago I made a respository of examples of polyvariadic functions, which you might find interesting, but which are fairly same-y and of dubious quality; I'm no professional even now, and that was a few years ago.
Method 1: Using seperate functions (No extensions)
A simple but crude method of doing this would simply be to define multiple functions to make a list with n elements, such as:
makeList1 :: a -> [a]
makeList2 :: a -> a -> [a]
-- etc.
-- Use:
myList = makeList5 1 2 3 4 5
This isn't so fantastic. Can we do better?
Method 2: Typeclasses (Requires FlexibleInstances)
This is much more interesting. Here, we sacrifice specificity to create a truly polyvariadic function:
{-# LANGUAGE FlexibleInstances #-}
class MkIntList r where
mkIntList' :: [Int] -> r
-- No arguments
instance MkIntList [Int] where
mkIntList' = id
-- One argument, then some others
instance (MkIntList r) => MkIntList (Int -> r) where
mkIntList' xs x = mkIntList' (xs ++ [x]) -- (Inefficient, but this is an illustration)
-- The variadic function
mkIntList :: (MkIntList r) => r
mkIntList = mkIntList []
-- Use:
myList1 = mkIntList 1 2 3 :: [Int] -- myList1 = [1,2,3]
myList2 = mkIntList :: [Int] -- myList2 = []
I'll leave you to get your head around this one.
Method 3: Functional Dependencies (Requires FlexibleInstances and FunctionalDependencies)
This is a polymorphic version of the previous one, in which we must keep track of the type via a functional dependency.
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE FunctionalDependencies #-}
class MkList a r | r -> a where
mkList' :: [a] -> r
instance MkList a [a] where
mkList' = id
instance (MkList a r) => MkList a (a -> r) where
mkList' xs x = mkList' (xs ++ [x]) -- (Again inefficient)
mkList :: (MkList a r) => r
mkList = retList []
-- Use:
myList1 = mkList 'H' 'i' '!' :: String -- myList1 = "Hi!"
myList2 = mkList True False :: [Bool] -- myList2 = [True, False]
I make a slightly more efficient version of this code a while ago.
Method 4: Metaprogramming (Requires Template Haskell)
This I think is the least theoretically interesting of the solutions, so I won't go into the frankly tedious examples.
This method involves creating a function which in turn generates Haskell code, via Template Haskell, which one can then use to generate the necessary function, based on the length of this list, at compile time. This is essentially a less labour-intensive (but slower at compile time) version of method 1.
Nowadays there are probably far more ways of doing this, but I hope that you find these examples helpful, or in the very least enlightening.
Mainly, the reason your approach isn't working is that (I think) you have slightly misunderstood map. Let's have a look at the type signature:
map :: (a -> b) -> [a] -> [b]
You can see here that the main restriction with map is that only one list is passed in as a parameter - so you can't pass multiple lists, which is what you have tried to do. The other reason this doesn't work is that map is specifically for applying a function to the elements within a list, and you're trying to use it between multiple lists, without changing the individual elements.
So how can you define your function? The problem here is that Haskell doesn't really support variadic functions (but see below). In Haskell, if you want to support any amount of arguments of the same type, you would join them together in a list; that is, fn [a, b, c] instead of fn a b c. So let's try that here: your function would be:
fn :: [[a]] -> [[a]]
fn = ???
So how do we implement this? What we want is a function which combines multiple lists, and we're given a list containing multiple lists (the arguments), so... the output is exactly the same as the input! At this point, we're probably better off ignoring fn - or indeed any attempted map (:) combination - and just writing the list ourselves. So your example would just be:
xs = [x1, x2, x3]
If even this doesn't work for you, and you really do want a variadic function, then I would suggest looking back over your program and checking whether it's using the best/easiest approach - remember the XY problem.
(Side note: if you really need it, and there's no way to solve your problem otherwise, then it is actually possible to define variadic functions in Haskell - search Haskell variadic function for more information. However, this approach is mostly useful when doing string formatting or advanced type-level stuff, making it unlikely that you would need such an approach.)

List of polymorphic functions in haskell?

Consider the code below:
t1 :: [Int] -> (Int,String)
t1 xs = (sum xs,show $ length xs)
t2 :: [Int] -> (Int,String)
t2 xs = (length xs, (\x -> '?') <$> xs)
t3 :: [Int] -> (Char,String)
t3 (x:xs) = ('Y',"1+" ++ (show $ length xs))
t3 [] = ('N',"empty")
These three functions have a type that only varies partially -- they are entirely usable without needing to know the type of the first component of the tuple they produce. This means that I can operate on them without needing to refer to that type:
fnListToStrs vs fs = (\x -> snd $ x vs) <$> fs
Loading these definitions into GHCi, all three of the functions work independently as an argument to fnListToStrs, and indeed I can pass in a list containing both t1 and t2 because they have the same type:
*Imprec> fnListToStrs [1,2] [t1,t2]
["2","??"]
*Imprec> fnListToStrs [1,2] [t3]
["1+1"]
But I can't pass all 3 at the same time, even though the divergence of types is actually irrelevant to the calculation performed:
*Imprec> fnListToStrs [1,2] [t1,t2]
["2","??"]
*Imprec> fnListToStrs [1,2] [t3]
["1+1"]
I have the feeling that making this work has something to do with either existential or impredicative types, but neither extension has worked for me when using the type declaration I expect fnListToStrs to be able to take, namely:
fnListToStrs :: [Int] -> [forall a.[Int]->(a,String)] -> [String]
Is there some other way to make this work?
Existential is correct, not impredicative. And Haskell doesn't have existentials, except through an explicit wrapper...
{-# LANGUAGE GADTs #-}
data SomeFstRes x z where
SFR :: (x -> (y,z)) -> SomeFstRes x z
> fmap (\(SFR f) -> snd $ f [1,2]) [SFR t1, SFR t2, SFR t3]
["2","??","1+1"]
but, this really is a bit useless. Since you can't possibly do anything with the first result anyway, it's more sensible to just throw it away immediately and put the remaining function in a simple monomorphic list:
> fmap ($[1,2]) [snd . t1, snd . t2, snd . t3]
["2","??","1+1"]
Any way to put these functions into a list will require "wrapping" each of them in some fashion. The simplest wrapping is just
wrap :: (a -> (b, c)) -> a -> c
wrap f = snd . f
There are, indeed, other ways to wrap these (notably with existential types), but you've not given any information to suggest that any of those would be even slightly better in your application than this simplest version.
Here's an example where something more sophisticated might make sense. Suppose you have
data Blob a b = Blob [a -> b] [a]
Now imagine you want to make a list of values of type Blob a b that all have the same b type, but may have different a types. Actually applying each function to each argument could lead to a prohibitively large list of potential results, so it would make sense to write
data WrapBlob b where
WrapBlob :: Blob a b -> WrapBlob b
Now you can make the list and postpone the decision of which function(s) to apply to which argument(s) without paying a prohibitive price.

Haskell recursive function example with foldr

I've taken up learning Haskell again, after a short hiatus and I am currently trying to get a better understanding of how recursion and lambda expressions work in Haskell.
In this: YouTube video, there is a function example that puzzles me far more than it probably should, in terms of how it actually works:
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
For the sake of clarity and since it wasn't immediately obvious to me, I'll give an example of applying this function to some arguments:
firstThat (>10) 2000 [10,20,30,40] --returns 20, but would return 2000, if none of the values in the list were greater than 10
Please correct me, if my assumptions are wrong.
It seems firstThat takes three arguments:
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
a list of values of the aforementioned type
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
So, how exactly does this function work? I apologize if I am being too dense or fail to see the forest for the trees, but I just cannot wrap my head around it, which is frustrating.
Any helpful explanation or example(s) would be greatly appreciated.
Thanks!
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening.
You are right. However, there is a nicer way of putting it than talking about "missing arguments" -- one that doesn't lead you into asking where they have gone. Here are two ways in which the arguments are not missing.
Firstly, consider this function:
add :: Num a => a -> a -> a
add x y = x + y
As you may know, we can also define it like this:
add :: Num a => a -> a -> a
add = (+)
That works because Haskell functions are values like any other. We can simply define a value, add, as being equal to another value, (+), which just happens to be a function. There is no special syntax required to declare a function. The upshot is that writing arguments explicitly is (almost) never necessary; the main reason why we do so because it often makes code more readable (for instance, I could define firstThat without writing the f parameter explicitly, but I won't do so because the result is rather hideous).
Secondly, whenever you see a function type with three arguments...
firstThat :: (a -> Bool) -> a -> [a] -> a
... you can also read it like this...
firstThat :: (a -> Bool) -> (a -> [a] -> a)
... that is, a function of one argument that produces a function of two arguments. That works for all functions of more than one argument. The key takeaway is that, at heart, all Haskell functions take just one argument. That is why partial application works. So on seeing...
firstThat :: (a -> Bool) -> a -> [a] -> a
firstThat f = foldr (\x acc -> if f x then x else acc)
... you can accurately say that you have written explicitly all parameters that firstThat takes -- that is, only one :)
The lambda expression provided as an argument to foldr seem to be missing its arguments too.
Not really. foldr (when restricted to lists) is...
foldr :: (a -> b -> b) -> b -> [a] -> b
... and so the function passed to it takes two arguments (feel free to add air quotes around "two", given the discussion above). The lambda was written as...
\x acc -> if f x then x else acc
... with two explicit arguments, x and acc.
a function that takes one arguments and returns a Boolean value. Since the > operator is actually an infix function, the first argument in the example above seems the result of a partial application to the > function – is this correct?
yes: (>10) is short for \x -> x > 10, just as (10>) would be short for \x -> 10 > x.
an unspecified value of the same type expected as the missing argument to the function provided as the first argument
first of all, it's not a missing argument: by omitting an argument, you obtain a function value. however, the type of the 2nd argument does indeed match the argument of the function >10, just as it matches the type of the elements of the list [10,20,30,40] (which is better reasoning).
a list of values of the aforementioned type
yes.
But the actual function firstThat seems to be defined differently from its type declaration, with just one argument. Since foldr normally takes three arguments I gathered there is some kind of partial application happening. The lambda expression provided as an argument to foldr seem to be missing its arguments too.
that's because given e.g. foo x y z = x * y * z, these 2 lines are equivalent:
bar x = foo x
bar x y z = foo x y z
— that's because of a concept called currying. Currying is also the reason why function type signatures are not (a, b) -> c but instead a -> b -> c, which in turn is equivalent to a -> (b -> c) because of the right associativity of the -> type operator.
Therefore, these two lines are equivalent:
firstThat f = foldr (\x acc -> if f x then x else acc)
firstThat f x y = foldr (\x acc -> if f x then x else acc) x y
Note: that you can also use Data.List.find combined with Data.Maybe.fromMaybe:
λ> fromMaybe 2000 $ find (>10) [10, 20, 30]
20
λ> fromMaybe 2000 $ find (>10) [1, 2, 3]
2000
See also:
https://en.wikipedia.org/wiki/Currying.
https://www.fpcomplete.com/user/EFulmer/currying-and-partial-application
http://learnyouahaskell.com/higher-order-functions

What does '#' mean in Haskell?

I've tried googling but come up short. I am furthering my Haskell knowledge by reading some articles and I came across one that uses a syntax I've never seen before.
An example would be:
reconstruct node#(Node a b c l r) parent#(Node b d le ri)
I've never seen these #'s before. I tried searching online for an answer but came up short. Is this simply a way to embed tags to help make things clearer, or do they have an actual impact on the code?
It is used in pattern matching. Now node variable will refer to the entire Node data type for the argument Node a b c l r. So instead of passing to the function as Node a b c l r, you can use node instead to pass it up.
A much simpler example to demonstrate it:
data SomeType = Leaf Int Int Int | Nil deriving Show
someFunction :: SomeType -> SomeType
someFunction leaf#(Leaf _ _ _) = leaf
someFunction Nil = Leaf 0 0 0
The someFunction can also be written as:
someFunction :: SomeType -> SomeType
someFunction (Leaf x y z) = Leaf x y z
someFunction Nil = Leaf 0 0 0
See how simpler was the first version ?
Using #t as a type indicator
Besides the argument pattern matching usage described in the answer of #Sibi, in Haskell the "at" character ('#', also known as an arobase character) can be used in some contexts to force a typing decision. This is mentioned in the comments by #Josh.F.
This is not part of the default language features, and is known as the Type Application Haskell language extension. In summary, the extension allows you to give explicit type arguments to a polymorphic function such as read. In a classic .hs source file, the relevant pragma must be included:
{-# LANGUAGE TypeApplications #-}
Example:
$ ghci
GHCi, version 8.2.2: http://www.haskell.org/ghc/ :? for help
λ>
λ> let x = (read #Integer "33")
<interactive>:4:10: error:
Pattern syntax in expression context: read#Integer
Did you mean to enable TypeApplications?
λ>
λ> :set -XTypeApplications
λ>
λ> let x = (read #Integer "33")
λ>
λ> :type x
x :: Integer
λ>
λ> x
33
λ>
Further details
For the read polymorphic function, the type indicator introduced by # relates to the type of the result returned by read. But this is not generally true.
Generally speaking, you have to consider the type variables that appear in the type signature of the function at hand. For example, let's have a look at the fmap library function.
fmap :: Functor ft => (a -> b) -> ft a -> ft b
So here, we have 3 type variables, in order of appearance: ft, a, b. If we specialize fmap like this:
myFmap = fmap #type1 #type2 #type3
then type1 will relate to ft, type2 will relate to a and type3 will relate to b. Also, there is a special dummy type indicator #_ which means: “here, any type goes”.
For example, we can force the output type of fmap to be Integer and the functor to be the plain list [], leaving the input type a unspecified:
λ>
λ> myFmap = fmap #[] #_ #Integer
λ>
λ> :type myFmap
myFmap :: (_ -> Integer) -> [_] -> [Integer]
λ>
As for the read function, its type is:
read :: Read a => String -> a
So there is only room for one type indicator, and it relates to the type of the result returned by read, as displayed above.

Inference of if ... then ... else strange behaviour

Considering the following bad code :
fun x =
if (null x) then 0
else (take 50 x) : (fun (drop 50 x))
I noticed, I can load it into ghci without any problem, and that's the problem.
The program only retrieve me an error when i try to evaluate this function.
Regarding the default inference rule of if ... then ... else expression, as the two branches explicitly retrieve different type, why this code can be load (ie compiled) ? I mean, why the compiler can't figured out this code is ill-formed ?
Note : Of course if i add the correct type annotation for this function, as expected it'll be rejected, but in my understanding it should be rejected too without the type annotation.
Overloaded numeric literals. Haskell numeric literals are instances of whatever Num classes are defined, based on the type context.
The inferred type explains it:
Prelude> let f x = if null x then 0 else take 50 x : f (drop 50 x)
Prelude> :t f
f :: Num [[a]] => [a] -> [[a]]
That reads as "if you have an instance of the Num class for lists of lists of a, then this function takes a list of a to a list of list of a.
So it relies on a mythical instance of Num for lists of lists. If you tried to compile code that used this, without providing an instance of numbers for lists of lists, it would be a compilation error.
This example also illustrates why it is a good idea to write down the type signature first.
Let's check this out.
Prelude> let fun x = if (null x) then 0 else (take 50 x) : (fun (drop 50 x))
Prelude> :t fun
fun :: Num [[a]] => [a] -> [[a]]
As you can see the compiler infers a Num class for your result type.

Resources