Why is the type for [tail, init, reverse], [[a] -> [a]]? - haskell

This question is in one of the Haskell textbook exercises, not so smart question.
Question: What are the types of the following values?
[tail, init, reverse]
Solution: [[a] -> [a]]
But why?

tail, init and reverse are functions defined on a generic list, [a]. You read [a] as "a list of any type abstracted as a", in particular, if a = Int, you get [Int] - list of integers.
Now, function that takes a list and outputs a list of the same type has signature [c] -> [c] or, if c = a, [a] -> [a]. The letter picked up does not matter as long as you have the same latter on both sides, because [a] -> [b] would mean that you take somehow a list of as and map it to a list of bs - which - in general - a different type. You could say that a = Int and b = String and therefore you'd have to map Int to String anyhow; also you could say that b = a an thus reduce to the [a] -> [a] case.
The last one: [tail, init, reverse] is obviously yet another list, where a = [b] -> [b]. So you got [ [b] -> [b] ] type or, equivalently, [ [a] -> [a] ] or [ [k] -> [k] ]. Again: particular letter does not matter as long as you stick to the chosen one.

The type of the following value, not "values". singular. List of three elements is a value. Or did you mean "each of the values in the given list"? then they all must have the same type. since a list has a type [t] for some t. which implies all its elements have that same type t, whatever that is. then since tail :: [a] -> [a], so must be the other two that appear in the same list.
On their own they could each refer to a different letter i.e. "type variable". but inside the same list, they all must be in agreement. thus the type of the list as a whole is [ [a] -> [a] ].

Related

Higher Order Functions evaluation

Create a high-order function in Haskell that takes in another function. That second function takes in a list and evaluates to each index to be true or false. The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
This is what I have so far
Bool _ _ = []
Bool f (x y :xs) = f x y : Bool f xs
Split your task into subtasks:
Create a high-order function in Haskell that takes in another function.
higherOrder :: (a -> b) -> Bool
higherOrder f = undefined -- a higher order function that takes
-- in another function
We have not learned anything about the type of the passed function, which is why we use the placeholder a -> b. This will be change later, once we learn more about f.
That second function takes in a list and evaluates to each index to be true or false.
This function is passed in. You don't need to implement it, it will be provided as an argument. You do however need to know its type signature, in this case
f :: [a] -> [Bool] -- a function taking a list of any type
-- ([a]), evaluating it to a list of booleans
-- example usage
f [1, 2, 3] == [True, False, True]
Which we use to update the type of our higherOrder
higherOrder :: ([a] -> [Bool]) -> Bool
The high order function should evaluate to true if the second function evaluates to true for at least 2 indexes in the list
You could replace this step with a simpler step: Write a function atLeastTwo :: [Bool] -> Bool, that takes a list of Booleans ([Bool]) and returns True if at least two indexes' values are true.
atLeastTwo :: [Bool] -> Bool
atLeastTwo xs = undefined
Maybe you can implement atLeastTwo by filtering the list, keeping only True values and then counting its length. You might find filter :: (a -> [Bool]) -> [a] -> [a] and length :: [a] -> Int1 useful.
Putting it all together you will discover that the task description is not clear. It does not talk about the list that is passed to higherOrder. In your case it probably should have been passed as a second parameter (xs) so we update higherOrder again to
higherOrder :: ([a] -> [Bool]) -> [a] -> Bool
higherOrder f xs = undefined
Proposal for an updated assignment
A more natural problem would be, where the passed function processes a list element (a -> Bool) instead of a list ( [a] -> [Bool]), and would read:
[Updated/alternative assignment: replacing ([a] -> [Bool]) with (a -> Bool).]
Implement a (higher-order) function atLeastTwoTrues :: (a -> Bool) -> [a] -> Bool. The first argument being passed to atLeastTwoTrues should be a function that can evaluate a value to either True or False. The second argument is a list of values. Your function should return True if and only if at least two elements of the passed list evaluate to True using the first argument.
This would avoid some ambiguity but is a different problem.
Good luck and enjoy your Haskell journey. It is difficult at the start. It has been for all of us. Don't give up, because once you start to master it, you will enjoy it.
1This is actually not the complete truth since length works with more data types than just lists and has a more general type.
Prelude> :t length
length :: Foldable t => t a -> Int

Couldn't match expected type error

As a beginner, I was working on item number 3 of the Haskell 99 problems. The first code snippet is my solution. However, I cannot add the type declaration of [a] -> Int -> a.
It produces an error: Couldn't match type 'a' with 'Int'
--My Solution
--elementAt :: [a] -> Int -> a
elementAt xs num = head . reverse $ takeWhile (<num+1) xs
Meanwhile, one of the solution in the problem 3 works perfectly with the same output.
elementAt' :: [a] -> Int -> a
elementAt' list i = list !! (i - 1)
I've used the :type in the GHCI for the elementAt without the declaration and it shows:
elementAt :: (Num c, Ord c) => [c] -> c -> c
What is the difference of the two functions?
takeWhile (<num+1) xs says that you want to take elements at the front of the list xs while the element (not the index!) is less than num + 1. Since you're comparing num (which is an Int) with the list elements, the compiler infers that the list elements have to be Int as well, which contradicts your type declaration.
Without the type declaration, GHC infers that xs's elements and num have to be the same type (since you compare list elements with num). This type has to have an Ord instance (for the comparison) as well as a Num instance (because of the addition).
The type of takeWhile (< num + 1) is [Int] -> [Int].
However the type of xs is [a].
Essentially you are trying to apply a predicate Int -> Bool to elements of type a.
If you want to filter based on the position in the list, you first need to augment the input list with the position of each element. You can do this fairly easily with zip:
zip xs [1..]
You can then drop elements based on the value of the second element of the resulting list.

Understanding Haskell types [duplicate]

This question already has answers here:
Understanding Haskell Type Signatures
(3 answers)
Closed 8 years ago.
I need to understand how types works and can be interpreted.
For example, if we take map function we have map :: (a -> b) -> [a] -> [b]
Well, how do I interpret this?
-> is a type constructor for the type of functions. It's a right-associative infix operator, meaning it's grouped together from the right. This means that we can rewrite the type by adding explicit grouping for the functions to the right side.
map :: (a -> b) -> [a] -> [b]
map :: (a -> b) -> ([a] -> [b])
An infix expression for an operator * applied to two arguments, x and y, x * y can be written in prefix notation as (*) a b. We can rewrite the preceding type, starting with the outermost ->, which is the one in the middle.
map :: (->) (a -> b) ([a] -> [b])
And we can now translate the last type into English
map :: (->) (a -> b) ([a] -> [b])
map is a function that takes a "(a -> b)" and returns a "([a] -> [b])"
Where we interpret a -> b ~ (->) a b (here ~ means the types are equivalent) as
(->) a b
function that takes an "a" and return a "b"
And interpret [a] -> [b] ~ (->) [a] [b] as
(->) [ a ] [ b ]
function that takes a list of "a"s and returns a list of "b"s
We say "a function from a to b" as shorthand for "a function that takes an a and returns a b"
The as and bs in the type signature are type variables, they can take on any type, which we call polymorphism. Occasionally, you will see this written explicitly in Haskell as forall So, in all we could say:
map is a polymorphic value for all types a and b which is a function that:
takes a function from a to b and
returns a function from a lists of as to a list of bs.
The fact that this signature contains -> tells us it's a function. Whatever comes after the last -> is the return type of the function once fully applied. Let's look at the individual pieces.
(a -> b)
This is the first argument, and it, too is a function. This means that map is a higher-order-function -- it takes a function as one of its arguments. a -> b itself is a function that transforms some value of type a into some value of type b.
[a]
The second argument. The square brackets is special syntax that denotes list. This argument, therefore, is a list with elements of type a.
[b]
The type of the result. Again, a list, but this time with elements of type b.
We can try to reason about this now. Given a function a -> b and a list of a, map seems to be (it really is) a function that transforms that list of as into a list of bs.
Here's an example: map (*2) [1,2,3]. In this case, a is Integer (or some other integer type) and each element is doubled. b, too, is Integer, because (*2) assumes the same return type, so in the case the type variables a and b are the same. This need not be the case; we could have a different function instead of (*2), say show which would have produced a b distinct from a, namely String.
Try them out in ghci. You can type in map show [1,2,3] directly and see the result. You can query the type of the expression by prepending :t to that line.
To learn more, you should look up one of the marvelous starter resources. LYAH has an entire chapter dedicated to the basic understanding of types, and is definitely worth a read!

Creating a list type using functions

For a silly challenge I am trying to implement a list type using as little of the prelude as possible and without using any custom types (the data keyword).
I can construct an modify a list using tuples like so:
import Prelude (Int(..), Num(..), Eq(..))
cons x = (x, ())
prepend x xs = (x, xs)
head (x, _) = x
tail (_, x) = x
at xs n = if n == 0 then xs else at (tail xs) (n-1)
I cannot think of how to write an at (!!) function. Is this even possible in a static language?
If it is possible could you try to nudge me in the right direction without telling me the answer.
There is a standard trick known as Church encoding that makes this easy. Here's a generic example to get you started:
data Foo = A Int Bool | B String
fooValue1 = A 3 False
fooValue2 = B "hello!"
Now, a function that wants to use this piece of data must know what to do with each of the constructors. So, assuming it wants to produce some result of type r, it must at the very least have two functions, one of type Int -> Bool -> r (to handle the A constructor), and the other of type String -> r (to handle the B constructor). In fact, we could write the type that way instead:
type Foo r = (Int -> Bool -> r) -> (String -> r) -> r
You should read the type Foo r here as saying "a function that consumes a Foo and produces an r". The type itself "stores" a Foo inside a closure -- so that it will effectively apply one or the other of its arguments to the value it closed over. Using this idea, we can rewrite fooValue1 and fooValue2:
fooValue1 = \consumeA consumeB -> consumeA 3 False
fooValue2 = \consumeA consumeB -> consumeB "hello!"
Now, let's try applying this trick to real lists (though not using Haskell's fancy syntax sugar).
data List a = Nil | Cons a (List a)
Following the same format as before, consuming a list like this involves either giving a value of type r (in case the constructor was Nil) or telling what to do with an a and another List a, so. At first, this seems problematic, since:
type List a r = (r) -> (a -> List a -> r) -> r
isn't really a good type (it's recursive!). But we can instead demand that we first reduce all the recursive arguments to r first... then we can adjust this type to make something more reasonable.
type List a r = (r) -> (a -> r -> r) -> r
(Again, we should read the type List a r as being "a thing that consumes a list of as and produces an r".)
There's one final trick that's necessary. What we would like to do is to enforce the requirement that the r that our List a r returns is actually constructed from the arguments we pass. That's a little abstract, so let's give an example of a bad value that happens to have type List a r, but which we'd like to rule out.
badList = \consumeNil consumeCons -> False
Now, badList has type List a Bool, but it's not really a function that consumes a list and produces a Bool, since in some sense there's no list being consumed. We can rule this out by demanding that the type work for any r, no matter what the user wants r to be:
type List a = forall r. (r) -> (a -> r -> r) -> r
This enforces the idea that the only way to get an r that gets us off the ground is to use the (user-supplied) consumeNil function. Can you see how to make this same refinement for our original Foo type?
If it is possible could you try and nudge me in the right direction without telling me the answer.
It's possible, in more than one way. But your main problem here is that you've not implemented lists. You've implemented fixed-size vectors whose length is encoded in the type.
Compare the types from adding an element to the head of a list vs. your implementation:
(:) :: a -> [a] -> [a]
prepend :: a -> b -> (a, b)
To construct an equivalent of the built-in list type, you'd need a function like prepend with a type resembling a -> b -> b. And if you want your lists to be parameterized by element type in a straightforward way, you need the type to further resemble a -> f a -> f a.
Is this even possible in a static language?
You're also on to something here, in that the encoding you're using works fine in something like Scheme. Languages with "dynamic" systems can be regarded as having a single static type with implicit conversions and metadata attached, which obviously solves the type mismatch problem in a very extreme way!
I cannot think of how to write an at (!!) function.
Recalling that your "lists" actually encode their length in their type, it should be easy to see why it's difficult to write functions that do anything other than increment/decrement the length. You can actually do this, but it requires elaborate encoding and more advanced type system features. A hint in this direction is that you'll need to use type-level numbers as well. You'd probably enjoy doing this as an exercise as well, but it's much more advanced than encoding lists.
Solution A - nested tuples:
Your lists are really nested tuples - for example, they can hold items of different types, and their type reveals their length.
It is possible to write indexing-like function for nested tuples, but it is ugly, and it won't correspond to Prelude's lists. Something like this:
class List a b where ...
instance List () b where ...
instance List a b => List (b,a) b where ...
Solution B - use data
I recommend using data construct. Tuples are internally something like this:
data (,) a b = Pair a b
so you aren't avoiding data. The division between "custom types" and "primitive types" is rather artificial in Haskell, as opposed to C.
Solution C - use newtype:
If you are fine with newtype but not data:
newtype List a = List (Maybe (a, List a))
Solution D - rank-2-types:
Use rank-2-types:
type List a = forall b. b -> (a -> b -> b) -> b
list :: List Int
list = \n c -> c 1 (c 2 n) -- [1,2]
and write functions for them. I think this is closest to your goal. Google for "Church encoding" if you need more hints.
Let's set aside at, and just think about your first four functions for the moment. You haven't given them type signatures, so let's look at those; they'll make things much clearer. The types are
cons :: a -> (a, ())
prepend :: a -> b -> (a, b)
head :: (a, b) -> a
tail :: (a, b) -> b
Hmmm. Compare these to the types of the corresponding Prelude functions1:
return :: a -> [a]
(:) :: a -> [a] -> [a]
head :: [a] -> a
tail :: [a] -> [a]
The big difference is that, in your code, there's nothing that corresponds to the list type, []. What would such a type be? Well, let's compare, function by function.
cons/return: here, (a,()) corresponds to [a]
prepend/(:): here, both b and (a,b) correspond to [a]
head: here, (a,b) corresponds to [a]
tail: here, (a,b) corresponds to [a]
It's clear, then, that what you're trying to say is that a list is a pair. And prepend indicates that you then expect the tail of the list to be another list. So what would that make the list type? You'd want to write type List a = (a,List a) (although this would leave out (), your empty list, but I'll get to that later), but you can't do this—type synonyms can't be recursive. After all, think about what the type of at/!! would be. In the prelude, you have (!!) :: [a] -> Int -> a. Here, you might try at :: (a,b) -> Int -> a, but this won't work; you have no way to convert a b into an a. So you really ought to have at :: (a,(a,b)) -> Int -> a, but of course this won't work either. You'll never be able to work with the structure of the list (neatly), because you'd need an infinite type. Now, you might argue that your type does stop, because () will finish a list. But then you run into a related problem: now, a length-zero list has type (), a length-one list has type (a,()), a length-two list has type (a,(a,())), etc. This is the problem: there is no single "list type" in your implementation, and so at can't have a well-typed first parameter.
You have hit on something, though; consider the definition of lists:
data List a = []
| a : [a]
Here, [] :: [a], and (:) :: a -> [a] -> [a]. In other words, a list is isomorphic to something which is either a singleton value, or a pair of a value and a list:
newtype List' a = List' (Either () (a,List' a))
You were trying to use the same trick without creating a type, but it's this creation of a new type which allows you to get the recursion. And it's exactly your missing recursion which allows lists to have a single type.
1: On a related note, cons should be called something like singleton, and prepend should be cons, but that's not important right now.
You can implement the datatype List a as a pair (f, n) where f :: Nat -> a and n :: Nat, where n is the length of the list:
type List a = (Int -> a, Int)
Implementing the empty list, the list operations cons, head, tail, and null, and a function convert :: List a -> [a] is left as an easy exercise.
(Disclaimer: stole this from Bird's Introduction to Functional Programming in Haskell.)
Of course, you could represent tuples via functions as well. And then True and False and the natural numbers ...

What to call a function that splits lists?

I want to write a function that splits lists into sublists according to what items satisfy a given property p. My question is what to call the function. I'll give examples in Haskell, but the same problem would come up in F# or ML.
split :: (a -> Bool) -> [a] -> [[a]] --- split lists into list of sublists
The sublists, concatenated, are the original list:
concat (split p xss) == xs
Every sublist satisfies the initial_p_only p property, which is to say (A) the sublist begins with an element satisfying p—and is therefore not empty, and (B) no other elements satisfy p:
initial_p_only :: (a -> Bool) -> [a] -> Bool
initial_p_only p [] = False
initial_p_only p (x:xs) = p x && all (not . p) xs
So to be precise about it,
all (initial_p_only p) (split p xss)
If the very first element in the original list does not satisfy p, split fails.
This function needs to be called something other than split. What should I call it??
I believe the function you're describing is breakBefore from the list-grouping package.
Data.List.Grouping: http://hackage.haskell.org/packages/archive/list-grouping/0.1.1/doc/html/Data-List-Grouping.html
ghci> breakBefore even [3,1,4,1,5,9,2,6,5,3,5,8,9,7,9,3,2,3,8,4,6,2,6]
[[3,1],[4,1,5,9],[2],[6,5,3,5],[8,9,7,9,3],[2,3],[8],[4],[6],[2],[6]]
I quite like some name based on the term "break" as adamse suggests. There are quite a few possible variants of the function. Here is what I'd expect (based on the naming used in F# libraries).
A function named just breakBefore would take an element before which it should break:
breakBefore :: Eq a => a -> [a] -> [[a]]
A function with the With suffix would take some kind of function that directly specifies when to break. In case of brekaing this is the function a -> Bool that you wanted:
breakBeforeWith :: (a -> Bool) -> [a] -> [[a]]
You could also imagine a function with By suffix would take a key selector and break when the key changes (which is a bit like group by, but you can have multiple groups with the same key):
breakBeforeBy :: Eq k => (a -> k) -> [a] -> [[a]]
I admit that the names are getting a bit long - and maybe the only function that is really useful is the one you wanted. However, F# libraries seem to be using this pattern quite consistently (e.g. there is sort, sortBy taking key selector and sortWith taking comparer function).
Perhaps it is possible to have these three variants for more of the list processing functions (and it's quite good idea to have some consistent naming pattern for these three types).

Resources