The difference between (a -> Bool) and (a -> a -> Bool) in Haskell? [closed] - haskell

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 4 years ago.
Improve this question
I am currently learning Haskell and came across a type signature that confused me.
I know that:
(a -> Bool)
Is how a predicate is assigned in the type signature when using (Ord a) but I came across a type signature that is declared as:
(a -> a -> Bool)
Which according to what I found online is a type signature for inequalities but I am confused as to if they are for adding an inequality to a predicate, ie:
(> p x == True)
Or if they are just to declare inequalities by themselves.
Thanks.

When some function has a typesignature (a -> Bool) it just means it takes a value of some unconstrained type a and returns a Bool, i.e. True or False. You can however restrict the type variable a and get something like this Ord a => a -> Bool, it restricts the polymorphic type a in that sense that a has to have an instance of type class Ord.
You can also partially apply functions. e.g (>) :: Ord a => a -> a -> Bool and when you partially apply > with 5 you get (>5) :: (Ord a, Num a) => a -> Bool. That is a new function that takes something that has to have the type class Ord as well as the type class Num, and returns True or False.
To answer your question, you can of course create a new function by applying a constant to another function. You also don't really need the == if all you want to do is, check if a number is strictly bigger than a constant.
f = (>) 5
f 4 -- True
f 5 -- False
I hope this helps you to get started with haskell. You should probably read some tutorial to get a good overview though. I can recommend learn you a haskell.

Related

Haskell - how to check if an element is in a list using Foldr? [duplicate]

This question already has answers here:
Implementation of function "member" using "foldr" in Haskell
(2 answers)
Closed 2 years ago.
I want to check whether a element is in a list, and I want to implement it using Foldr. I know it is wrong, but I can't get any further than the code below
func :: Eq a => a -> [a] -> Bool
func a b = foldr (==) a b
I furthermore got the first line of code from the lectures, but I don't really understand why Eq a is necessary and what it does.
If you want to check if an element a is in a list you need to compare it to each element in the list. Thus whatever type a is, it needs to implement Eq.
With :t foldr in e.g. ghci, you can see the type signature your inner function which I will call f needs:
foldr :: Foldable t => (a -> b -> b) -> b -> t a -> b
If you use (==) for f it does not work because you can only compare a list element to a Bool which should ultimately indicate whether a is in the list.
So you need to figure out how to get a, the element you want to test for into f.

How to find the kth element of an 'infinite' Foldable structure in Haskell? [closed]

Closed. This question is not reproducible or was caused by typos. It is not currently accepting answers.
This question was caused by a typo or a problem that can no longer be reproduced. While similar questions may be on-topic here, this one was resolved in a way less likely to help future readers.
Closed 5 years ago.
Improve this question
I'd like to define a function, safeIndex that works on Foldable types
safeIndex :: (Foldable t, Integral i) => t a -> i -> Maybe a
safeIndex = foldr step (const Nothing)
where
step :: Integral i => a -> (i -> Maybe a) -> i -> Maybe a
step x f i = if i == 0
then Just x
else f (i - 1)
But it doesn't work for infinite lists. For foldr to stop in the middle, I think we have to determine whether it should stop only with the first argument of step, which seems impossible.
Is it possible to fix the function so that it works on infinite structures? If not, what typeclasses should we restrict t to?
Actually the definition in the question description already works for infinite built-in list. It was some other mistakes that make me thought it couldn't ;) (See the comments.)
If you don't mind taking on a dependency, the foldl library from Gabriel Gonzalez provides index and genericIndex folds which suit your purpose.
For example, you could write
safeIndex :: (Foldable f, Integral a) => a -> f b -> Maybe b
safeIndex = fold . genericIndex
Besides that, the code you posted seems to do what you intend.
EDIT: I spaced the "infinite lists" bit.
This will work for infinite lists, but I don't know that there's a sensible way to define it for all Foldables.
safeIndex' :: Int -> [a] -> Maybe a
safeIndex' n = listToMaybe . foldr (.) id (replicate n (drop 1))
EDIT 2:
Scratch that, what you've got in the original post ought to work for any Foldable.

Are all arguments in haskell read from left to right? [closed]

Closed. This question needs details or clarity. It is not currently accepting answers.
Want to improve this question? Add details and clarify the problem by editing this post.
Closed 5 years ago.
Improve this question
For example:
f :: (b -> c) -> (a -> b) -> c
g h
he function f takes two functions (lets call them g and h) as input-arguments, and returns a value of type c
First argument: (a -> b)
Second argument: (b -> c)
Returns: a value of type c
In order for this function definition to be true the types have to line up, like this: (a -> b) -> (b -> c) <=equivalent to=> a -> c
and the only way for this to work is if the second argument is used as input for the first argument, like this g(h(x)), where x is of type a, is this true for all functions in Haskell? In other words
is the right argument always going to be defined as the input for its left argument? And is this the general case for all composed functions in Haskell?
And if so should I always read and interpret function-arguments from right to left instead of left to right?
OBS:
This question is not the same question as:
Why does the dot compose from right to left in haskell
Because my question is more general for all functions, also I already know that a function composed of other functions is called function compositon, and I know about the dot-function etc.
I think you might be confusing things a little. In your example, replicated below:
f :: (b -> c) -> (a -> b) -> c
Here f is a higher order function, which means that it can take other functions as parameters. As a matter of fact, its first parameter is a function of type (b -> c). Its second argument is a function of type (a -> b).
The parameters of a function do not have to be related to each other at all. In your case, it was simply a coincidence. We could have easily done something like this:
g :: (Int -> Double) -> (Char -> Bool) -> String
g func1 func2 = "three"
Another thing to be aware of is that all functions in Haskell are curried. Think back to a language like C:
char foo (int a, double b) { ... }
The function takes (int, double) and returns a char. We might even write its type signature like this:
(int, double) -> char
In Haskell, we don't require all parameters to be fed in at once, and it is expressed as this:
int -> double -> char
Why in the world would you want this? Consider the following scenario:
add :: Int -> Int -> Int
add a b = a + b
Check this out:
addFive :: Int -> Int
addFive = add 5
Applying less arguments than the function's parameter requires allows you to create new functions that are somewhat "customized". Pretty cool, huh? :)

Why does the type of a function change when it comes out of a monad in GHCi [duplicate]

This question already has an answer here:
Why does `peek` with a polymorphic Ptr return GHC.Prim.Any when used with a bind?
(1 answer)
Closed 6 years ago.
Something changes about the type of a function when it comes out of a monad.
In GHCI:
> :t map
map :: (a -> b) -> [a] -> [b]
> a <- return map
> :t a
a :: (GHC.Prim.Any -> GHC.Prim.Any)
-> [GHC.Prim.Any] -> [GHC.Prim.Any]
This change makes it hard to store the function in a higher rank type.
What is happening here and can I make it not happen?
(Also doesn't this violate one of the monad laws?)
First of all, there is no point in doing anything like a <- return map - its the same as let a = map, which works just fine. That said, I don't think that is your question...
Checking out the documentation of GHC.Prim.Any which gives us a big hint as to the role of Any.
It's also used to instantiate un-constrained type variables after type
checking. For example, length has type
length :: forall a. [a] -> Int
and the list datacon for the empty list has type
[] :: forall a. [a]
In order to compose these two terms as length [] a
type application is required, but there is no constraint on the
choice. In this situation GHC uses Any
(In terms of type application syntax, that looks like length #Any ([] #Any *))
The problem is that when GHCi sees x <- return map it tries to desugar it to return map >>= \x -> ... but the ... part is whatever you enter next into GHCi. Normally it would figure out what the type variables of map are going to be instantiated to (or whether they even should be instantiated to anything) based the ..., but since it has nothing there.
Another key point that #sepp2k points out is that x can't be given a polymorphic type because (>>=) expects (on its RHS) a rank-1 function, and that means its argument can't be polymorphic. (Loosening this condition pushes you straight into RankNTypes at which point you lose the ability to infer types reliably.)
Therefore, needing x to be monomorphic and having no information to help it instantiate the type variables that prevent x from being monomorphic, it defaults to using Any. That means that instead of (a -> b) -> [a] -> [b] you get (Any -> Any) -> [Any] -> [Any].

How to Interpret (Eq a)

I need to create a function of two parameters, an Int and a [Int], that returns a new [Int] with all occurrences of the first parameter removed.
I can create the function easily enough, both with list comprehension and list recursion. However, I do it with these parameters:
deleteAll_list_comp :: Integer -> [Integer] -> [Integer]
deleteAll_list_rec :: (Integer -> Bool) -> [Integer] -> [Integer]
For my assignment, however, my required parameters are
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
I don't know how to read this syntax. As Google has told me, (Eq a) merely explains to Haskell that a is a type that is comparable. However, I don't understand the point of this as all Ints are naturally comparable. How do I go about interpreting and implementing the methods using these parameters? What I mean is, what exactly are the parameters to begin with?
#groovy #pelotom
Thanks, this makes it very clear. I understand now that really it is only asking for two parameters as opposed to three. However, I still am running into a problem with this code.
deleteAll_list_rec :: (Eq a) => a -> [a] -> [a]
delete_list_rec toDelete [] = []
delete_list_rec toDelete (a:as) =
if(toDelete == a) then delete_list_rec toDelete as
else a:(delete_list_rec toDelete as)
This gives me a "The type signature for deleteAll_list_rec
lacks an accompanying binding" which makes no sense to me seeing as how I did bind the requirements properly, didn't I? From my small experience, (a:as) counts as a list while extracting the first element from it. Why does this generate an error but
deleteAll_list_comp :: (Eq a) => a -> [a] -> [a]
deleteAll_list_comp toDelete ls = [x | x <- ls, toDelete==x]
does not?
2/7/13 Update: For all those who might stumble upon this post in the future with the same question, I've found some good information about Haskell in general, and my question specifically, at this link : http://learnyouahaskell.com/types-and-typeclasses
"Interesting. We see a new thing here, the => symbol. Everything before the => symbol is >called a class constraint. We can read the previous type declaration like this: the >equality function takes any two values that are of the same type and returns a Bool. The >type of those two values must be a member of the Eq class (this was the class constraint).
The Eq typeclass provides an interface for testing for equality. Any type where it makes >sense to test for equality between two values of that type should be a member of the Eq >class. All standard Haskell types except for IO (the type for dealing with input and >output) and functions are a part of the Eq typeclass."
One way to think of the parameters could be:
(Eq a) => a -> [a] -> [a]
(Eq a) => means any a's in the function parameters should be members of the
class Eq, which can be evaluated as equal or unequal.*
a -> [a] means the function will have two parameters: (1) an element of
type a, and (2) a list of elements of the same type a (we know that
type a in this case should be a member of class Eq, such as Num or
String).
-> [a] means the function will return a list of elements of the same
type a; and the assignment states that this returned list should
exclude any elements that equal the first function parameter,
toDelete.
(* edited based on pelotom's comment)
What you implemented (rather, what you think you implemented) is a function that works only on lists of Integers, what the assignment wants you to do is create one that works on lists of all types provided they are equality-comparable (so that your function will also work on lists of booleans or strings). You probably don't have to change a lot: Try removing the explicit type signatures from your code and ask ghci about the type that it would infer from your code (:l yourfile.hs and then :t deleteAll_list_comp). Unless you use arithmetic operations or similar things, you will most likely find that your functions already work for all Eq a.
As a simpler example that may explain the concept: Let's say we want to write a function isequal that checks for equality (slightly useless, but hey):
isequal :: Integer -> Integer -> Bool
isequal a b = (a == b)
This is a perfectly fine definition of isequal, but the type constraints that I have manually put on it are way stronger than they have to. In fact, in the absence of the manual type signature, ghci infers:
Prelude> :t isequal
isequal :: Eq a => a -> a -> Bool
which tells us that the function will work for all input types, as long as they are deriving Eq, which means nothing more than having a proper == relation defined on them.
There is still a problem with your _rec function though, since it should do the same thing as your _comp function, the type signatures should match.

Resources