Using lists in Haskell - haskell

I'm trying to learn list in Haskell but I have a error that I don't understand
I've been trying to definition arguments, but honestly I don't understand too much of haskell yet.
lefgNLista:: [Int]->[Int]->Int
lefgNLista []=[]
lefgNLista (fre1:fre2) fre3 = if fre1 == fre3 then 1+lefgNLista else fre1 : lefgNLista fre2
Also tried like this but got another error
lefgNLista []=[]=0
I expect the function to count the amount of N numbers in the list, e.g.
ghci> lefgNLista [1,3,5,7,8,8,2,3,8] 8
3

Here is a possible definition explained item by item.
I will omit the type. You can give this function the type of [Int]->[Int]->Int if you want, but it's not the best possible type. The compiler is able to infer the best type for you.
There are two parts in the definition, one for the empty list and one for non-empty lists.
How many elements are in an empty list? Zero. How many of those are equal to any given value? Also zero.
lefgNLista [] _ = 0
-- [] ⇒ the empty list
-- _ ⇒ "any given element", we are not looking at it, hence no name
-- = ⇒ "is defined as"
-- 0 ⇒ that's zero
OK now let's look at a non-empty list. This part has two further cases. We look at the first element of the list. Either it equals to what we are counting, or not.
lefgNLista (x:xs) y | x == y = 1 + lefgNLista xs y
| otherwise = lefgNLista xs y
-- (x:xs) ⇒ A customary way to name a list pattern
-- y ⇒ The value we want to count
-- | ⇒ Pronounced "when"
-- x == y ⇒ Self evident
-- = ⇒ "is defined as"
-- 1 + lefgNLista xs y ⇒ Compute for the rest of list and add 1 
-- | otherwise = ⇒ Self evident
-- lefgNLista xs y ⇒ Just compute for the rest of list
So what is the type of this inferred by Haskell?
Prelude λ :t lefgNLista
lefgNLista :: (Num p, Eq t) => [t] -> t -> p
This is not as intimidating as it seems. You can read this as "when p is some kind of number, and t is some kind of stuff you can check for equality, the type is [t] -> t -> p". So this function works for Int, Double, (Int, Int) or any other type you can compare — even for other lists!
Prelude λ lefgNLista [[1,2], [3,5], [1,2]] [1,2]
2
What about Num p? Int is not the only type you can count with. You may need Integer if your lists are extremely long, or you may want to use your own fancy number-like type, but this is probably way too advanced at this point.

Related

How to implement the function find with the filter function?

I'm making some exercise to practice my Haskell skills. My task is to implement the Haskell function find by myself with the filter function.
I already implemented the find function without the filter function (see codeblock below) but now my problem is to implement it with filter function.
-- This is the `find` function without `filter` and it's working for me.
find1 e (x:xs)= if e x then x
else find1 e xs
-- This is the find function with the filter function
find2 e xs = filter e xs
The result of find1 is right
*Main> find1(>4)[1..10]
Output : [5].
But my actual task to write the function with filter gives me the
*Main> find2(>4)[1..10]
Output : [5,6,7,8,9,10].
My wanted result for find2 is the result of find1.
To "cut a list" to only have one, head element in it, use take 1:
> take 1 [1..]
[1]
> take 1 []
[]
> take 1 $ find2 (> 4) [1..10]
[5]
> take 1 $ find2 (> 14) [1..10]
[]
If you need to implement your own take 1 function, just write down its equations according to every possible input case:
take1 [] = []
take1 (x:xs) = [x]
Or with filter,
findWithFilter p xs = take1 $ filter p xs
Your find1 definition doesn't correspond to the output you show. Rather, the following definition would:
find1 e (x:xs) = if e x then [x] -- you had `x`
else find1 e xs
find1 _ [] = [] -- the missing clause
It is customary to call your predicate p, not e, as a mnemonic device. It is highly advisable to add type signatures to all your top-level definitions.
If you have difficulty in writing it yourself you can start without the signature, then ask GHCi which type did it infer, than use that signature if it indeed expresses your intent -- otherwise it means you've coded something different:
> :t find1
find1 :: (t -> Bool) -> [t] -> [t]
This seems alright as a first attempt.
Except, you actually intended that there would never be more than 1 element in the output list: it's either [] or [x] for some x, never more than one.
The list [] type is too permissive here, so it is not a perfect fit.
Such a type does exist though. It is called Maybe: values of type Maybe t can be either Nothing or Just x for some x :: t (read: x has type t):
import Data.Maybe (listToMaybe)
find22 p xs = listToMaybe $ filter p xs
We didn't even have to take 1 here: the function listToMaybe :: [a] -> Maybe a (read: has a type of function with input in [a] and output in Maybe a) already takes at most one element from its input list, as the result type doesn't allow for more than one element -- it simply has no more room in it. Thus it expresses our intent correctly: at most one element is produced, if any:
> find22 (> 4) [1..10]
Just 5
> find22 (> 14) [1..10]
Nothing
Do add full signature above its definition, when you're sure it is what you need:
find22 :: (a -> Bool) -> [a] -> Maybe a
Next, implement listToMaybe yourself. To do this, just follow the types, and write equations enumerating the cases of possible input, producing an appropriate value of the output type in each case, just as we did with take1 above.

Haskell tuple not matching with function argument

I'm new to Haskell so it may be obvious but I did Prolog extensively so I'm perplex about this one...
When using GHCi, I created the following function (1):
Prelude> let find k t = head [v | (k',v) <- t, k == k'] -- Definiton of find
find :: Eq a1 => a1 -> [(a1, a)] -> a
Prelude> find 2 [(1,11),(2,22)] -- Invocation of find
22
Which is expected. I then tried to remove the k' from the definition:
Prelude> let find2 k t = head [v | (k,v) <- t]
find2 :: t -> [(t1, a)] -> a
Prelude> find2 2 [(1,11),(2,22)]
11
I was then very surprised to see the value 2 actually matched with 1.
Just to be sure I was not hoping for the impossible I also try the following in order to confirms that partial matching is possible in Haskell, which looks like it is actually the case:
Prelude> head [v | (2,v) <- [(1,11),(2,22)]]
22
I also noticed a difference in the function declarations. I added the required information so both declarations for find and find2 look exactly the same. But the result is still broken (2,_) matchnig (1,11):
Prelude> let find2 :: Eq a1 => a1 -> [(a1, a)] -> a; find2 k t = head [v | (k,v) <- t]
find2 :: Eq a1 => a1 -> [(a1, a)] -> a
Prelude> find2 2 [(1,11),(2,22)]
11
How can 2 be matching 1 by any mean?
(1) The above function comes from the excellent book "Programming in Haskell" p.93
Yes, Haskell pattern matching is fundamentally different from Prolog pattern matching.
In Haskell, a variable in a pattern refers to a fresh variable that will be bound by the match, never an existing variable that must be matched. So, the expression:
let x = 5 in case (1,2) of (x,y) -> "matched!" -- gives "matched!"
will always evaluate to "matched!". That's because the x in (x,y) gets freshly bound to 1, not compared with the value of the "existing", outer definition of x, as you can see here:
let x = 5 in case (1,2) of (x,y) -> x -- gives "1"
The behavior is different for numeric constants:
case (1,2) of (5,y) -> "matched!" -- match fails
and for other constructors:
case (True,2) of (False,y) -> "match!" -- match fails
which are not "re-bound" but rather must match for the pattern match to succeed. This is one of many reasons that alphanumeric constructors start with capital letters: otherwise, it would tremendously difficult to determine whether a pattern involved matching to an existing constructor or rebinding to a fresh variable.
This applies to pattern matches in any context, whether it's case expressions as above or function definitions like this:
let x = 5
f x = "hi" -- defines `f` for any `x`, not just `f 5`
or list comprehensions like your example. In the expression:
[v | (k,v) <- [(1,2),(3,4)]] -- gives [(1,2),(3,4)]
the variables k and v will always be fresh, so will bind to any of the tuples despite any outer, existing definitions of k or v. If you turn on warnings with -Wall (specifically -Wname-shadowing), this will alert you to the shadowed binding. If you replace k with a constant (or other constructor), it behaves differently:
[v | (3,v) <- [(1,2),(3,4)]] -- only gives [(3,4)]
You may not like it, but that's just the way Haskell works.
Thanks for your help! After some searches, I also found this answer to be helpful: How can I re-assign a variable in a function in Haskell?
A new variable having the same name is created that shadows the previous one. But the first variable continues to exist and in some cases be still accessible...
So indeed this is far from Prolog and yes the following flag is of precious help:
Prelude> :set -fwarn-name-shadowing

A function that returns maximum of list and count of occurrences

I'm writing a recursive function mxAndC. When I give it a list, it should return a tuple. The tuple will have the maximum of the given list as its first element and the second element will be the number of times the element occurs in the list. Assignment does not allow me to create a helper function. I'm expecting following output:
mxAdC "bananas" = (s,1)
mxAdC "banana" =(n,2)
mxAdC [mod x 4 | x <- [1..50]] -> (3,12)
I did the following:
mxAdC = go 0
where go count (x:xs)
| count /= 0 = (mx, count)
| null ((x:xs)) = error "The list is empty"
| x == mx = go (count+1) xs
where mx = maximum (x:xs)
And I'm getting error:
* Ambiguous type variable `a0' arising from a use of `go'
prevents the constraint `(Ord a0)' from being solved.
Relevant bindings include
mxAdC :: [a0] -> (a0, Integer) (bound at hw06.hs:24:1)
Probable fix: use a type annotation to specify what `a0' should be.
These potential instances exist:
instance (Ord a, Ord b) => Ord (Either a b)
-- Defined in `Data.Either'
instance Ord Ordering -- Defined in `GHC.Classes'
instance Ord Integer
-- Defined in `integer-gmp-1.0.0.1:GHC.Integer.Type'
...plus 23 others
...plus 38 instances involving out-of-scope types
(use -fprint-potential-instances to see them all)
* In the expression: go 0
In an equation for `mxAdC':
mxAdC
= go 0
where
go count (x : xs)
| count /= 0 = (mx, count)
| null ((x : xs)) = error "The list is empty"
| x == mx = go (count + 1) xs
where
mx = maximum (x : xs)
I'm very new in Haskell. Would any benevolent expert out there like to reach out and help out this newbie?
A fairly straightforward implementation would use filter:
mxAdC :: Ord a => [a] -> (a,Int)
mxAdC xs = (mx,length $ filter (\x -> x == mx) xs) where mx = maximum xs
You hit the dreaded Monomorphism Restriction.
You can fix the type error by
using mxAdC x = go 0 x
putting {-# LANGUAGE NoMonomorphismRestriction #-} at the beginning of your file
adding the type signature
Your function is still wrong, but now it typechecks.
Haskell prohibits polymorphic functions that look like top-level constants (don't have parameters before the = sign). So in general you cannot eta-reduce (replace foo x = bar x with foo = bar). The full explanation is rather long - see this answer: https://stackoverflow.com/a/32496865/805266
Others have explained the type error. Let's look at the more interesting mistakes.
| null ((x:xs)) = error "The list is empty"
What's wrong? x : xs is never null. It can't possibly be, because its first element is x! What you meant to do here was
mxAdC ys
| null ys = error "mxAdC: the list is empty"
| otherwise = go 0 ys
where ...
The next problem is
| count /= 0 = (mx, count)
This says that as soon as the count is non-zero, you're done. So you'll never get above 1. You recognized that your recursion needed a base case, so you tried to put one in, but you missed the mark. The base case you need is to deal with the empty list:
go count [] = ?
go count (x:xs)
| x == mx = go (count+1) xs
Something is still missing from go, however. What do you want to happen when x /= mx? You need to add one more case (I've left question marks for you to fill in):
go count [] = ?
go count (x:xs)
| x == mx = go (count+1) xs
| otherwise = ?
The final major problem is that you defined mx within the go function. This will calculate the maximum of whatever piece of the list go was handed, each time. What you want to do is define mx in mxAdC
mxAdc ys
| ....
where
go ...
mx = maximum ys
There are still two big efficiency problems to deal with. One problem is that go no longer forces calculation of the accumulator in the recursive call, which may lead to a space leak. This is easily fixed using the BangPatterns language extension with
go !count [] = ?
go !count (x:xs)
| x == mx = go (count+1) xs
| otherwise = ?
The last problem is that you still traverse the list twice: once to calculate the maximum and then again to count how many times it occurs. It's possible to do it in just one pass. I won't give you all the details, but the basic trick is to change your go function to take the greatest element seen thus far as well as the number of times it's been seen. You'll have to adjust the rest of mxAdC to fit, using a pattern match to get things going instead of null.

What does (:) do in Haskell? [duplicate]

This question already has answers here:
What does the : infix operator do in Haskell?
(4 answers)
Closed 8 years ago.
I've tried looking it up in hoogle and other various haskell dictionaries, but I can't find it. I was under the impression that it prepends, but I'm starting to see it in ways I haven't before and I've started second guessing myself.
For example, this is one of the questions that I don't understand:
(3 points) Fill in the blank with a pattern such that fun1 [(5,6),(7,8)] returns
5 and fun1 [(10,20),(30,40),(50,60)] returns 10:
and the answer is apparently:
((y,_):_)
fun1 _____________ = y
But I am so confused by this. I understand that the underscores mean that you don't really care about what the types of those are, but I don't understand what the (:) does in this answer.
While the other answers correctly explain what : is they don't quite answer the question - in the answer you have in your question : isn't used as a function, but as a constructor to pattern match on. fun (x:xs) = x means "if the argument is of the format (x:xs) give me the x". Pattern matching is used to "pull apart" complex types based on their constructors in Haskell.
In particular, since : is a list constructor you can pull apart lists with :
(conceptually list is defined as data [] a = [] | (:) a [a], although you're not gonna get this to compile because it's builtin syntax).
A non list example: We could define a datatype data F a b = A a | B b. This would create a type F that's parameterized with two types a and b and two constructors A and B with the types a -> F a b and b -> F a b respectively.
You could then write functions that use pattern matching to get at the contained values, like
isA (A _) = True -- this value was constructed with A, so it is an A
isA (B _) = False -- this value was constructed with B so it is not an A
or
getA (A a) = a -- this value was constructed with A so we can get an a out of it
getA (B _) = undefined -- ohps! We can't get an a back here cause we don't have one!
It is a List constructor function. It is used for prepending any value in front of the list.
ghci> 2 : [3,4]
[2,3,4]
It is just another Haskell function. You can also see it's type in ghci:
ghci> :t (:)
(:) :: a -> [a] -> [a]
Regarding your question, the answer is like this ((y,_):_) because it is being used in pattern matching. The first _ is the second element of the pair and the second _ pattern matches a list.
This may help you:
ghci> (5,6):[(7,8)]
[(5,6),(7,8)]
: is the list constructor of type a -> [a] -> [a]. It is usually used infix. but you can use it as prefix if you surround it with parentheses as you did. Just like any infix operation. (E.g. (+) 4 5 == 4 + 5)
So (:) a as is the same as a:as
Every constructor in Haskell can be also used do deconstruct a value of the type if constructs in a pattern match:
f x:xs = xs
would for example define a function that takes a non empty list and returns the tail. It would fail on an empty list because the empty list is constructed by the nullary constructor []. You could make f total by adding that second constructor to the match.
f [] = []
I guess your confusion comes from the fact that in haskell there is syntactic sugar that allows you to write lists in a more convenient way. Instead of (1:(2:(3:[]))) you can write [1,2,3] which is expanded into the former by the compiler.
In addition to the answers of what (:) function does, please, bear in mind that in the context of your question : is used as a deconstructor.
It is better to view (:) as a constructor. Then, just like any other data constructor, it can be used to introspect the contents of the value. Examples are:
f (Just x) = x -- extracts the value wrapped into Maybe a
f (x:_) = x -- extracts the value wrapped into a list, [a]
f ((x,_):_) = x -- extracts the value wrapped into a tuple in the list of tuples
In all these cases Just, : and (,) are constructors. The same syntax can be used to construct or deconstruct the values - depending on the context of the expression. Compare:
f x = Just x -- wraps x into Maybe a
f x xs = x:xs -- wraps x into a list, [a]
f x y z = (x,y):z -- wraps x into a tuple in the list of tuples
To understand what fun1 does, let's first look at another function:
f (x:xs) = x
If you pass this function a list such as [5,12,33], it will match x to 5, and xs to [12,33]. The function just returns x, i.e. the first element. So this function is basically the same as head. Since we don't actually use the value xs, we can rewrite the function as:
f (x:_) = x
Now let's look at fun1, but a slightly modified version.
fun1 ((y,z):xs) = y
If we pass this function the list [(5,6),(7,8)], it will match (y,z) to the pair (5,6) and xs to [(7,8)]. So now y is 5, and that's the value we return. Again, since we don't use z or xs, we can write the function as:
fun1 ((y,_):_) = y

Is "List" specially handled in Haskell's pattern matching?

I am a newbie in Haskell and hope this question is not silly.
I have seen so much example that when I am having a list, I am able to match and bind "composition element" of the list to individual variable:
listSizeDesc :: [a] -> String
listSizeDesc [] = "Emtpy"
listSizeDesc (x:xs) = "Something inside"
However, I tried to do something like:
foo :: Int -> String
foo 0 = "Zero"
foo (n - 1) = "next number is " ++ show n
It doesn't work.
It seems to me that both (n-1) and (x:xs) describe how the argument is "created" and bind the "component" to an argument. Is the way List matched specially designed for ease of recursion? Coz it seems to me this matching / argument-binding logic doesn't apply to other functions except (:).
The problem you're encountering is that pattern matching only works with data constructors. A data constructor is in essence very simple; it just takes data values and groups them together in some sort of structure. For example, data Foo = Bar a b simply takes two pieces of data and groups them together under the Foo label. The (:) function you use in your first example is more than just a function; it's a data constructor. It constructs a new list by adding the left argument to the right argument.
Now, pattern matching is merely doing the opposite of this process. It deconstructs a datatype. When you write (x:xs) in your pattern, you're extracting the two pieces of data that the constructor originally stitched together. So all pattern matching does is extract the data that a constructor previously stitched together.
There is one exception: n+k patterns. In Haskell98, you were allowed to use patterns of the form (n+k). This was sort of an arbitrary exception and it was recently removed. If you'd like, you can still use it if you include the NPlusKPatterns language pragma.
The list type is "Sum type" with a constructor, something like:
data List a =
cons a (List a)
| nil
You first example is a pattern match on a datatype (with syntactic sugar for :).
Your second example is a pattern match on integers, which are not a datatypye definition. On integer, there is no pattern using your syntax. You may write your example with:
foo :: Int -> String
foo 0 = "Zero"
foo n = "next number is " ++ show (n+1)
On a side note if you encode integers with datatypes like:
data Nat = Zero | Succ Nat deriving (Show)
Then you can use your pattern match as you wanted initially.
foo :: Nat -> String
foo Zero = "Zero"
foo n#Succ(p) = "next number is " ++ show(n)
Here the pattern Succ(p) plays the role of n-1.
There are already some great answers, so I won't bother with the main question. This is not the best use of it, but what you were trying to do can sort of be accomplished with view patterns.
{-# LANGUAGE ViewPatterns #-}
foo :: Int -> String
foo 0 = "Zero"
foo (pred -> n) = "Next number is " ++ show n
Just to put it as simply as possible:
A list literally is a series of concatenations. A number could be equivalent to the result of an arithmetic operation. The difference is that the result of a : b is simply a : b.
In more detail:
Lists and (:) aren't a special case at all. Let's make our own:
data List2 a = End -- equivalent of "[]"
| Cat a (List2 a) -- non-infix ":"
deriving (Show)
So [1, 2, 3], which == (1 : (2 : (3 : []))), would be written as:
a = Cat 1 (Cat 2 (Cat 3 End))
Just like pattern-matching (x:xs), we can pattern-match List2:
newTail End = End
newTail (Cat _ x) = x
Test it:
*Main> tail [1,2,3]
[2,3]
*Main> newTail a
Cat 2 (Cat 3 End)
moo :: Int -> String
moo 0 = "Zero"
moo n = "next number is " ++ show (n + 1)
n - 1 is an ordinary function application, not a pattern. An exception used to be made for + and this might be the model you are going by. You can write something like
goo :: Int -> String
goo 0 = "Zero"
goo (n+1) = "previous number is " ++ show n
in hugs ; you still can do this with the ghc, if you include the pragma
{-#LANGUAGE NPlusKPatterns#-}

Resources