difference between (a -> a) and a -> a - function

I've noticed that (although I was once told that (a -> a) and a -> a meant the same thing), I get error messages when I use the (a -> a). Should I only use (a -> a) when using brackets amongst the types? (i.e. (5 + 3) instead of 5 + 3)? Just not quite certain of when it's necessary

(a -> a) and a -> a are the same alone,
ff :: (a -> a) -- this compiles
ff = id
gg :: a -> a
gg = id
h :: a -> a -> Bool
h _ _ = True
i = h ff gg -- this compiles => ff & gg are of the same type.
but will be different when combined with more types like:
a -> a -> b
(a -> a) -> b
This is because -> is right-associative, so a -> a -> b actually means a -> (a -> b) (take an a and return a function), which is different from (a -> a) -> b (take a function and return a b).
This is like (1+2)*3 is different from 1+2*3.

Parenthesization disambiguates several constructs in Haskell, when other information available to the compiler doesn't help:
Application associates to the left
so you can omit parens on function arguments.
Expressions involving infix operators are disambiguated by the operator's fixity.
so no need for parens in many cases with binary operators of different fixity.
Consecutive unparenthesized operators with the same precedence must both be either left or right associative to avoid a syntax error.
and finally:
Given an unparenthesized expression x op y op z, parentheses must be added around either x op y or y op z, unless certain conditions about precendence hold
My general advice, if the above statements don't make any sense: over-parenthesize things, until you learn the rules. Or, study the Haskell Report very hard.

Consider the expression 10 / 2 / 5. Is that the same as (10 / 2) / 5 or 10 / (2 / 5)? If you interpret / to be mathematical division, then the former is true, while the latter is false. So you see, the answer to your question is "there is a difference, but only sometimes".
Types are the opposite. a -> b -> c is the same as a -> (b -> c), and definitely not the same as (a -> b) -> c.
You say you're not quite sure when it's necessary: well here it is. When the argument to your function is also a function, then it is necessary.
Consider map :: (a -> b) -> [a] -> [b]. This is different than a -> b -> [a] -> [b], for you see, (a -> b) indicates a specific kind of function: a function from type a to type b.
iterate :: (a -> a) -> a -> [a] is more interesting. This function requires that the input and output types of the function in the first parameter must be the same.
You may be interested in reading up on currying and partial application. One good resource among many: Learn you a Haskell # Curried Functions

This only makes a difference when you're making higher order functions. For example:
f :: a -> a -> b
is a function that expects two arguments of type a and return a value of type b, like so
f 2 2
f True True
But the function
f :: (a -> a) -> b
Expects a function as an argument. The only time where a -> a and (a -> a) are the same if they're the only argument in type inference, like here
f :: (a -> a)
-- Same type as
f :: a -> a
The rules for () in typing are pretty much the same as in normal expressions. It's like expressions a level above.

They are the same. Could you describe the errors you get when you use (a -> a)? It works fine for me with ghci-7.0.3:
Prelude> let f :: (a -> a); f = id
Prelude> f "foo"
"foo"
Prelude>
In general, you need to use parentheses in types when you're using functions as arguments. For example, map :: (a -> b) -> [a] -> [b]. Without the parens, it would mean something else.

Related

Haskell High Order Functions, Function Declaration

I am studying for an exam and I'm confused at this function. Based on the output how do I know that the type declaration of the function is (a -> b -> c)? also, how I can evaluate my function?
zipWith' :: (a -> b -> c) -> [a] -> [b] -> [c]
zipWith' _ [] _ = []
zipWith' _ _ [] = []
zipWith' f (x:xs) (y:ys) = f x y : zipWith' f xs ys
What I understand is that high order functions in haskell mean that they take a function as a parameter and return a function as well, right? how can I call this particular function?
I did this:
zipWith' [1..5] ['a','z','r']
but I know is wrong because I am calling it as if it were the regular zip function that takes 2 lists and returns a tuple. I am just confused at the type declaration
zipWith' :: [a] -> [b] -> [(a,b)]
For this answer, we'll acknowledge that all functions are curried. That is, every function has a type a -> b, where a and b are some type.
A higher-order function is one whose type includes a function for either its argument or return type. Return values are easy: it's any function you ordinary think of as taking more than one argument:
take :: Int -> [a] -> [a]. It takes an Int and returns a (polymorphic) function that takes a list and returns a list.
map :: (a -> b) -> [a] -> [b]. It takes a function (literally any function) and returns a function from lists to lists. The types of the return value is determined by the type of the argument.
Higher-order functions that take an function and return something that isn't a function are actually somewhat rare. Perhaps a commenter will point out an obvious one I am overlooking, but until then, consider fix :: (a -> a) -> a.
Now, zipWith' is an example of a higher-order function whose argument itself must be a higher-order function. The general type a -> b can unify with an ordinary function like ord :: Char -> Int (a ~ Char and b ~ Int) as well as a higher-order function like (+) (with a ~ Num t => t and b ~ Num t => t -> t. The type a -> b -> c will only unify with higher-order functions. a may or may not be a function type, but b -> c is an explicit function type.
This means that once you apply zipWith' to some higher-order function, type inference gives you more information about what the types of [a], [b], and [c] must be in the resulting function.
zipWith' (+) tells you that a ~ b ~ c ~ Num t => [t].
zipWith' (,) tells you that a and b are still unrestricted, but c ~ (a, b)
zipWith' (:) tells you that a is unrestricted, but b ~ c ~ [a].
It may also help if you consider that zip :: [a] -> [b] -> [(a,b)] could be defined as zip = zipWith' (,).

Haskell function definition, missing argument? [duplicate]

This question already has answers here:
Haskell recursive function example with foldr
(2 answers)
Closed 6 years ago.
module Tf0 where
all' :: (a -> Bool) -> [a] -> Bool
all' p = foldr (&&) True . map p
main :: IO()
xs = [1,3,5,7,9]
xs1 = [1,3,11,4,15]
k1 = all' (<10) xs
k2 = all' (<10) xs1
k3 = all' (<10)
main = print k1
Questions:
In the function definition (all' p = foldr (&&) True . map p) there is no list as an input while the function Type shows a list as an input ([a]), yet trying to check the function (see bellow k1, k2, k3) shows that a list is needed.
How can the function be defined without the list?
One of the fundamental aspects of Haskell is that conceptually a function always takes one argument. Indeed take for instance the function (+):
(+) :: Int -> Int -> Int
(technically it is (+) :: Num a => a -> a -> a, but let us keep things simple).
Now you can argue that (+) takes two arguments, but conceptually it takes one argument. Indeed: the signature is in fact
(+) :: Int -> (Int -> Int)
So you feed it one integer and now it returns a function, for instance:
(+) 5 :: Int -> Int
So you have, by giving it a 5, constructed a function that will add 5 to a given operand (again a function that takes one argument).
Now applying this to your question, the signature of all' is in fact:
all' :: (a -> Bool) -> ([a] -> Bool)
So if you apply all' with one argument, it returns a function that maps a list [a] to a Bool. Say for the sake of argument that we set p to \_ -> True, then we return:
foldr (&&) True . map (\_ -> True) :: [a] -> Bool
so indeed a function that takes a list [a] and maps it on a Bool. In a next phase you apply a list to that (returning) function.
In other words, functional programming can be seen as a long chain of specializing a function further and further until it is fully grounded and can be evaluated.
Haskell only provides this in an elegant way such that you do not have to think about functions generating functions. But conceptually, this happens all the time. Given you want to implement a function f :: a -> b -> c, you can do this like:
f x y = g (x+1) y
(with g :: a -> b -> c), but you can also decide to leave a parameter out, and define it as:
f x = g (x+1)
since g (x+1) will return a function that can apply with the y eventually.

Ambiguous type variable in polyvariadic curry definition

So, I'm trying to implement a polyvariadic ZipWithN as described here. Unfortunately, Paczesiowa's code seems to have been compiled with outdated versions of both ghc and HList, so in the process of trying to understand how it works, I've also been porting it up to the most recent versions of both of those (ghc-7.8.3 and HList-0.3.4.1 at this time). It's been fun.
Anyways, I've run into a bug that google isn't helping me fix for once, in the definition of an intermediary function curryN'. In concept, curryN' is simple: it takes a type-level natural number N (or, strictly speaking, a value of that type), and a function f whose first argument is an HList of length N, and returns an N-ary function that takes makes an HList out of its first N arguments, and returns f applied to that HList. It's curry, but polyvariadic.
It uses three helper functions/classes:
The first is ResultType/resultType, as I've defined here. resultType takes a single function as an argument, and returns the type of that function after applying it to as many arguments as it will take. (Strictly speaking, again, it returns an undefined value of that type).
For example:
ghci> :t resultType (++)
resultType (++) :: [a]
ghci> :t resultType negate
resultType negate :: (ResultType a result, Num a) => result
(The latter case because if a happens to be a function of type x -> y, resultType would have to return y. So it's not perfect applied to polymorphic functions.)
The second two are Eat/eat and MComp/mcomp, defined together (along with curryN') in a single file (along with the broken curryN') like this.
eat's first argument is a value whose type is a natural number N, and returns a function that takes N arguments and returns them combined into an HList:
ghci> :t eat (hSucc (hSucc hZero))
eat (hSucc (hSucc hZero)) :: x -> x1 -> HList '[x, x1]
ghci> eat (hSucc (hSucc hZero)) 5 "2"
H[5, "2"]
As far as I can tell it works perfectly. mcomp is a polyvariadic compose function. It takes two functions, f and g, where f takes some number of arguments N. It returns a function that takes N arguments, applies f to all of them, and then applies g to f. (The function order parallels (>>>) more than (.))
ghci> :t (,,) `mcomp` show
(,,) `mcomp` show :: (Show c, Show b, Show a) => a -> b -> c -> [Char]
ghci> ((,,) `mcomp` show) 4 "str" 'c'
"(4,\"str\",'c')"
Like resultType, it "breaks" on functions whose return types are type variables, but since I only plan on using it on eat (whose ultimate return type is just an HList), it should work (Paczesiowa seems to think so, at least). And it does, if the first argument to eat is fixed:
\f -> eat (hSucc (hSucc hZero)) `mcomp` f
works fine.
curryN' however, is defined like this:
curryN' n f = eat n `mcomp` f
Trying to load this into ghci, however, gets this error:
Part3.hs:51:1:
Could not deduce (Eat n '[] f0)
arising from the ambiguity check for ‘curryN'’
from the context (Eat n '[] f,
MComp f cp d result,
ResultType f cp)
bound by the inferred type for ‘curryN'’:
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3.hs:51:1-29
The type variable ‘f0’ is ambiguous
When checking that ‘curryN'’
has the inferred type ‘forall f cp d result (n :: HNat).
(Eat n '[] f, MComp f cp d result, ResultType f cp) =>
Proxy n -> (cp -> d) -> result’
Probable cause: the inferred type is ambiguous
Failed, modules loaded: Part1.
So clearly eat and mcomp don't play as nicely together as I would hope. Incidentally, this is significantly different from the kind of error that mcomp (+) (+1) gives, which complains about overlapping instances for MComp.
Anyway, trying to find information on this error didn't lead me to anything useful - with the biggest obstacle for my own debugging being that I have no idea what the type variable f0 even is, as it doesn't appear in any of the type signatures or contexts ghci infers.
My best guess is that mcomp is having trouble recursing through eat's polymorphic return type (even though what that is is fixed by a type-level natural number). But if that is the case, I don't know how I'd go about fixing it.
Additionally (and bizarrely to me), if I try to combine Part1.hs and Part2.hs into a single file, I still get an error...but a different one
Part3alt.hs:59:12:
Overlapping instances for ResultType f0 cp
arising from the ambiguity check for ‘curryN'’
Matching givens (or their superclasses):
(ResultType f cp)
bound by the type signature for
curryN' :: (MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
at Part3alt.hs:(59,12)-(60,41)
Matching instances:
instance result ~ x => ResultType x result
-- Defined at Part3alt.hs:19:10
instance ResultType y result => ResultType (x -> y) result
-- Defined at Part3alt.hs:22:10
(The choice depends on the instantiation of ‘cp, f0’)
In the ambiguity check for:
forall (n :: HNat) cp d result f.
(MComp f cp d result, Eat n '[] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
To defer the ambiguity check to use sites, enable AllowAmbiguousTypes
In the type signature for ‘curryN'’:
curryN' :: (MComp f cp d result, Eat n [] f, ResultType f cp) =>
Proxy n -> (cp -> d) -> result
Failed, modules loaded: none.
Again with the mysterious f0 type variable. I'll admit that I'm a little bit over my head here with all this typehackery, so if anyone could help me figure out what exactly the problem here is, and, more importantly, how I can fix it (if it is, hopefully, possible), I'd be incredibly grateful.
Final note: the reasons that the two files here are called Part1 and Part3 is that Part2 contains some auxiliary functions used in zipWithN, but not curryN'. For the most part they work fine, but there are a couple of oddities that I might ask about later.

Type Inferring of function Haskell

Im trying to infer the type of:
((.) foldr)
The type i manually infer differs from the one ghci infer. Here's what i do:
(.) :: ( b -> c) -> (a->b)->a->c
foldr:: (a'->b'->b')->b'->[a']->b'
Now my first doubt. Foldr has to unify with b->c foldr has to unify with (b->c) but there are more than one way to make it happen; like
b ~ (a'->b'->b')
c ~ b'->[a']->b'
or..
b ~ (a'->b'->b')b'->[a']
c ~ b'
How do i know which to take?
Doing different examples in ghci i arrived to the conclusion that haskell tries to unify types in a non greedy fashion for the first argument (This conclusion is totally experimental and can be totally wrong, maybe its the reason i arrive to a wrong type for the function, but is what i thought of the type inferences ive tried on haskell). So, assuming this is true the configuration haskell tries to unify first is:
b ~ (a'->b'->b')
c ~ b'->[a']->b'
So now..
(.)foldr :: (a->b)->a->c
Substituting b and c:
(.)foldr :: (a-> (a'->b'->b') )->a->b'->[a']->b'
Which is close enough the only problem i have are the parentheses in the expression
(a'->b'->b')
Why can i remove them when you cannot remove those in the original foldr, and the function is gonna be an input for foldr. Why after applying the composition functor you can use partial application? Is there a rule for that?
Also i would like if someone coudl confirm or deny the "non greedy" type matching..
The associativity of ->
In Haskell the only type of function is a -> b, which is a function that takes an a and "returns" a b. For this reason a function type of:
a -> b -> c
is implicitly:
a -> (b -> c)
that is a function that takes an a and returns a function that takes a b and returns a c. You just have to remember that -> is right associative. This is the "mechanism" that allows currying.
Answers
How do i know which to take?
So, in your example:
foldr:: (a' -> b' -> b') -> b' -> [a'] -> b'
becomes:
foldr:: (a' -> b' -> b') -> (b' -> ([a'] -> b'))
As you can see the only way to infer a type a -> b is by assigning (a'->b'->b') to a and (b'->([a']->b')) to b.
Why can I remove them when you cannot remove those in the original foldr, and the function is gonna be an input for foldr?
Because after the function composition, the type is:
(a -> (a' -> b' -> b')) -> a -> b' -> [a'] -> b'
-- ^^^^^^^^^^^^^^^^^^^^
Let's focus on the first part:
(a -> (a' -> b' -> b'))
this is, for the right associativity of ->, equal to:
(a -> (a' -> (b' -> b')))
which is also equal to:
(a -> a' -> b' -> b')
for the same associativity rule.
Why after applying the composition functor you can use partial application? Is there a rule for that?
Partial application can be always applied when you have a function taking more than 1 "argument" (or more correctly, when you have a function that returns a function).
In type signature, (->) is right associative, which implies that
a -> b -> c
which is the type of a function that takes an argument of type a and return another function of type b -> c, equals
a -> (b -> c)
However, it does not equals
(a -> b) -> c
which is the type of a function that takes another function of type a -> b as its only argument and return a value of type c.
Question 1:
How do i know which to take?
You should choose first version, as you already did, because
(a'->b'->b')->b'->[a']->b'
equals
(a'->b'->b')->(b'->[a']->b')
And this is called currying, not greedy.
Question 2:
Why can i remove them when you cannot remove those in the original foldr
The same reason.

Is there a name for this function or pattern?

Instead of fmap, which applies a function to a value-in-a-functor:
fmap :: Functor f => (a -> b) -> f a -> f b
I needed a function where the functor has a function and the value is plain:
thing :: Functor f => f (a -> b) -> a -> f b
but I can't find one.
What is this pattern called, where I apply a function-in-a-functor (or in an applicative, or in a monad) to a plain value?
I've implemented it already, I just don't quite understand what I did and why there wasn't already such a function in the standard libraries.
You don't need Applicative for this; Functor will do just fine:
apply f x = fmap ($ x) f
-- or, expanded:
apply f x = fmap (\f' -> f' x) f
Interestingly, apply is actually a generalisation of flip; lambdabot replaces flip with this definition as one of its generalisations of standard Haskell, so that's a possible name, although a confusing one.
By the way, it's often worth trying Hayoo (which searches the entirety of Hackage, unlike Hoogle) to see what names a function is often given, and whether it's in any generic package. Searching for f (a -> b) -> a -> f b, it finds flip (in Data.Functor.Syntax, from the functors package) and ($#) (from the synthesizer package) as possible names. Still, I'd probably just use fmap ($ arg) f at the use site.
As Niklas says, this is application in some applicative functor to a lifted value.
\f a -> f <*> pure a
:: Applicative f => f (a -> b) -> a -> f b
or more generally (?), using Category (.)
\f a -> f . pure a
:: (Applicative (cat a), Category cat) => cat b c -> b -> cat a c