First Haskell program - haskell

i write a little code in Haskell to learn haskell. It looks like:
first :: [Int] -> Int -> Int
first [] x = x
first xs y = y
I wanted to express that i get a list([] or xs) and an argument(x or y) and no matter how the lists look like, the argument should presented.
So, when I write the following: first [1,2,3] 4, then ghci says:
Couldnt match expected type ´a0 -> t´ wth actual type ´[t0]´. Relevant bindings
include it :: t(boudn at <>:6:1)but its type ´[t 0]´ has none
In the expression : [1,2,3] 4
In an equation for ´it´: it = [1,2,3] 4
How can i fix it? What mistakes i´ve made? Can someone help me?

It looks like you use [1,2,3,4] 4 instead of first [1,2,3,4] 4.
> [1,2,3,4] 4
<interactive>:1:0:
Couldn't match expected type `t1 -> t' against inferred type `[a]'
In the expression: [1, 2, 3, 4] 4
In the definition of `it': it = [1, 2, 3, 4] 4
By the way, your definition of first is the same as the following:
first :: [Int] -> Int -> Int
first _ x = x
which means no matter what the first argument is, always returns the second argument.

Related

ERROR: no instance for (Num Char) arising from the literal `1'

insert_at insert an element e into a list xs in specific location n
testgetting Left if n less than 0
test2 getting Left if n larger than xs's length or The type e isn't match the element's type in listxs. Otherwise passing Right xs to the next.
import Data.Typeable
insert_at :: a -> [a] -> Int -> [a]
insert_at e xs n = a++(e:b) where
t = splitAt n xs
a = fst t
b = snd t
test :: (Ord a, Num a) => b -> a -> Either [Char] b
test xs n = if n < 0 then Left "n<0" else Right xs
test2 :: (Typeable a1, Typeable a2) =>
a1 -> [a2] -> Int -> Either [Char] [a2]
test2 e xs n
| n> ( length xs )= Left "n> $ length xs "
| (typeOf e) /= (typeOf (head xs) ) = Left "(typeOf e) /= (typeOf (head xs) ) "
|otherwise = Right xs
sf :: Typeable a => a -> [a] -> Int -> Either [Char] [a]
sf e xs n = test xs n >>test2 e xs n >> Right (insert_at e xs n)
All the other error got properly handled, expect this.
* No instance for (Num Char) arising from the literal `1'
* In the expression: 1
In the second argument of `sf', namely `[1, 2, 3, 4, ....]'
In the expression: sf 'a' [1, 2, 3, 4, ....] 3
The error message states that you're trying to evaluate the expression sf 'a' [1, 2, 3, 4, ....] 3. Since this expression is not shown in your question, I'm assuming you're using it in GHCi to test out your code, right?
The type signature of sf says that the first parameter has type a, and the second parameter has type [a], which is a list whose elements are of the same type as the first parameter.
So the compiler sees that the first parameter is 'a'. That's a character, type Char.
"Got it," - thinks the compiler, - "now I know that a is Char. And now I know that the second parameter must have type [Char] - that is, a list of Char".
And yes, the second parameter is indeed a list, but wait! The first element of the list is not a character, but number 1! That does not compute!
Fortunately, number literals are special in Haskell. Number literals are not merely of type Int or even of type Integer, no! Numbers can be of any type as long as that type has an instance of class Num.
So since the compiler already knows that the elements of that list must be of type Char, but it sees a number literal, it concludes that it must now find an instance of class Num for type Char.
But there is no such instance! And so the compiler rightly complains: "no instance Num Char"
To fix the problem, I need to better understand what you were actually trying to do.
Did you intend the whole function to work on numbers? Then the first parameter must be a number, not a character.
Or did you intend it to work on characters? Then the second parameter must be a list of characters, not numbers.
Or did you intend the first two parameters not to be the same type at all? Then you must change the type signature of sf to indicate that.
sf expects a value and a list as its first two arguments. The elements of the list must have the same type as the first argument. This is the meaning of
sf :: a -> [a] -> ...
When you write sf 'a' [1], this means 1 and 'a' must have the same type. So the type checker looks for a way to interpret 1 as a Char; it fails, because this is not possible. Some fixes might include:
sf 'a' "1234" 3
sf 'a' [toEnum 1, toEnum 2, toEnum 3, toEnum 4] 3
sf (fromEnum 'a') [1, 2, 3, 4] 3

Simple print in haskell script: how to write main function?

I am starting to learn haskell, but cannot find a way to have a working main function. I have already made it work somehow, but I think it was pure luck because I cannot get it again.
Basically, what I want to do is create a script file to be run like runhaskell script.hs from terminal.
So the basic structure would be the function declaration followed by a main = do or something, and the function being called to print its result.
For example, I took this from "Learn you a Haskell", but the following code doesn't work:
elem' :: (Eq a) => a -> [a] -> Bool
elem' y ys = foldl (\acc x -> if x == y then True else acc) False ys
main :: IO()
main = print (elem' 1 [1,2,3,4])
This gives me the error:
Build FAILED
/home/helton/Desktop/apaga.hs: line 6, column 16:
Warning: Defaulting the following constraint(s) to type `Integer'
(Eq a0)
arising from a use of elem'
at /home/helton/Desktop/apaga.hs:6:16-20
(Num a0)
arising from the literal `1' at /home/helton/Desktop/apaga.hs:6:22
In the first argument of `print', namely `(elem' 1 [1, 2, 3, 4])'
In a stmt of a 'do' block: print (elem' 1 [1, 2, 3, 4])
In the expression: do { print (elem' 1 [1, 2, 3, 4]) }
print (elem' 1 [1,2,3,4])
While I expected something like
> True
Try replacing
print (elem' 1 [1, 2, 3, 4])
with
print (elem' (1::Int) [1, 2, 3, 4])
The issue here is that Haskell can't determine whether your numeric literals should be interpreted as Ints or Doubles or any other numeric type.
Specifying the type for any numeric literal here is enough, since elem' requires all of them to be of the same type, hence once the type of any one of them is known such type can be used for everything else.

Haskell beginner order function

My code:
isOrdered :: (a -> a -> Bool) -> [a] -> Bool
isOrdered mark xs =(head xs) `mark`(head(tail xs))
Compiles perfectly but when I try to call it with
isOrdered < [1,2,3]
I get an error:
Couldn't match expected type `(a0 -> a0 -> Bool) -> [a0] -> Bool'
with actual type `[t0]'
In the second argument of `(<)', namely `[1, 2, 3]'
In the expression: isOrdered < [1, 2, 3]
In an equation for `it': it = isOrdered < [1, 2, 3]
What am I missing here?
Since < is infix, you have to wrap it in parens. This converts it to be prefixed.
1 < 2 ==> (<) 1 2
1 + 5 ==> (+) 1 5
Then you're code becomes
isOrdered (<) [1, 2, 3]
This is actually part of a more general concept of sectioning. You can completely convert an infix operator to prefix with parens, or partially apply it like this
\x -> x + 1 ===> (+1)
\x -> 2 ^ x ===> (2^)
The only place where this goes a bit pear-shaped is with -. Since - is a super special prefix operator defined by the Haskell language, you can't do (-2), since it's not clear whether this is a section or a number. Haskell chooses a number, but if you want a section, there is a function subtract.
\x -> x - 2 ==> subtract 2
This works:
isOrdered (<) [1,2,3]
Not sure why, though. It’s a general thing:
Prelude> :type <
<interactive>:1:1: parse error on input `<'
Prelude> :type (<)
(<) :: Ord a => a -> a -> Bool
I’m sure others will explain.
When passing an operator to a higher level function, you have to surround it with parentheses:
isOrdered (<) [1, 2, 3]
You also have to do this for partially applied operators
map (== 2) [1, 2, 3]
This is not an answer to your question, but just a stylistic tip: idiomatic Haskell code should use pattern matching instead of head/tail. Pattern matching statically ensures that you don't accidentally try to access inexistent elements.
The way you would write your function using pattern matching is:
isOrdered :: (a -> a -> Bool) -> [a] -> Maybe Bool
isOrdered mark (x:y:_) = Just (x `mark` y)
isOrdered _ _ = Nothing
Note that I've included a case for when the list does not contain two elements and wrapped the result in a Maybe. This prevents run-time errors by forcing you to handle that case.

Get third element of tuple

I have a tuple (1, 2, 3) and want to get the third element, however, I keep getting type errors.
Please see the below code:
third (hd : tl) = snd tl
third tpl = head$tail$tail tpl
How can I fix the type errors that are occuring and get the third element correctly?
Tuples aren't lists
In you're code, you're manipulating lists, :, head and tail all work on lists. So
third tpl = head . tail . tail . tail $ tpl
third' (_:_:x:_) = x
Will give you the third element.
a = [1, 2, 3]
>> third a
3
>> third (1, 2, 3)
Error expecting list, but got tuple
Instead you're going to have to use a function of type
thd :: (a, b, c) -> c
This function doesn't exist in the standard libs, it's completely trivial
thd (_, _, a) = a
And that's it :)
You're getting tuples confused with lists:
-- Tuples: Fixed length, mixed types, uses parenthesis
myTuple :: (Int, String)
myTuple = (1, "Hello")
-- Lists: Variable length, single type, uses square brackets
myList :: [Int]
myList = [1, 2, 3, 4]
-- Pattern matching a 3-tuple
isRightTriangle :: (Int, Int, Int) -> Bool
isRightTriangle (a, b, c) = a^2 + b^2 == c^2
-- Pattern matching a 2-tuple
name :: (String, Int) -> String
name (n, a) = n
-- or: name = fst
age :: (String, Int) -> Int
age (n, a) = a
-- or: age = snd
-- Pattern matching a list
thirdElem :: [a] -> a
thirdElem (x1:x2:x3:xs) = x3
thirdElem _ = error "List must have at least 3 elements"
-- or: thirdElem xs = head $ tail $ tail xs
If you haven't already, you should check out Learn You a Haskell For Great Good. It's a great, fun to read introduction to Haskell, starting out with the basic types like strings, tuples, numbers, and lists.

is mult_add a real function? What does it do?

I have the following question given to me.
Write a function form_number_back that takes a list of positive integers and forms a decimal number using the numbers in the list in reverse order.
For example form_number_back [1, 2, 3, 4] should return the number 4321;
form_number_back [ ] returns 0
Use the function foldr and mult_add below to accomplish this mult_add d s = d + 10*s
Note: foldr and foldr1 are two different functions. Try to use foldr1 instead of foldr in your definition and see if you get the same results with an empty list. Explain your results.
I cannot find anything on mult_add. I thought mabye it was the function name but she wants form_number_back as the function name. Which means mult_add is a Haskell function.
Can anyone explain to me what mult_add does? Is it even written right? Is mult_add another usermade function i'm supposed to use with my own code?
Edit 2
I tried putting in the function example to get its type..
so..
form_number_back [1, 2, 3, 4] :: Num b => b -> [b] -> b
so my function looks like
form_number_back a = foldr(mult_add)
but is returning type of
form_number_back :: Num b => [t] -> b -> [b] -> b
Trying to figure out how to get rid of that [t]
Types are both more important and more informative in Haskell than in most other languages. When you don't understand Haskell, a good first step is to think about types. So let's do that. We'll fire up ghci and enter:
Prelude> let mult_add d s = d + 10 * s
And now ask for its type:
Prelude> :t mult_add
mult_add :: Num a => a -> a -> a
That is, mult_add takes an a and another a, and returns an a, with the proviso that a is an instance of the Num class (so that you can add and multiply them).
You're asked to use foldr to write this function, so let's look at the type of that:
Prelude> :t foldr
foldr :: (a -> b -> b) -> b -> [a] -> b
That looks a bit intimidating, so let's break it down. The first part, (a -> b -> b) tells us that foldr needs a function of two variables, a and b. Well, we have one of those already - it's mult_add. So what happens if we feed in mult_add as the first argument to foldr?
Prelude> :t foldr mult_add
foldr mult_add :: Num b => b -> [b] -> b
Okay! We now have a function that takes a b and a [b] (a list of bs) and returns a b. The function you're trying to write needs to return 0 when it's given the empty list, so let's try feeding it the empty list, with a few different values for the remaining argument:
Prelude> foldr mult_add 10 []
10
Prelude> foldr mult_add 5 []
5
Hey, that's interesting. If we feed it the number x and the empty list, it just returns x (Note: this is always true for foldr. If we give it the initial value x and the empty list [], it will return x, no matter what function we use in place of mult_add.)
So let's try feeding it 0 as the second argument:
Prelude> foldr mult_add 0 []
0
That seems to work. Now how about if we feed it the list [1,2,3,4] instead of the empty list?
Prelude> foldr mult_add 0 [1,2,3,4]
4321
Nice! So it seems to work. Now the question is, why does it work? The trick to understanding foldr is that foldr f x xs inserts the function f between every element of xs, and additionally puts x at the end of the list, and collects everything from the right (that's why it's called a right fold). So, for example:
foldr f 0 [1,2,3] = 1 `f` (2 `f` (3 `f` 0))
where the backticks indicate that we're using the function in its infix form (so its first argument is the one on the left, and the second argument is the one on the right). In your example you have f = mult_add, which multiplies its second argument by 10 and adds it to the first argument:
d `mult_add` s = d + 10 * s
so you have
foldr mult_add 0 [1,2,3] = 1 `mult_add` (2 `mult_add` (3 `mult_add 0))
= 1 `mult_add` (2 `mult_add` 3)
= 1 `mult_add` 32
= 321
which does what you expect. To make sure you understand this, work out what would happen if you defined mult_add the other way around, i.e.
mult_add d s = 10 * d + s

Resources