why is function name repeated in haskell? (newbie) - haskell

Why is the function name repeated in
example:
lucky :: (Integral a) => a -> String
lucky 7 = "LUCKY NUMBER SEVEN!"
lucky x = "Sorry, you're out of luck, pal!"
when should I not be repeating function name? what is the meaning of it?
thanks

What you are seeing is pattern match in action.
I will show you another example:
test 1 = "one"
test 2 = "two"
test 3 = "three"
Demo in ghci:
ghci> test 1
"one"
ghci> test 2
"two"
ghci> test 3
"three"
ghci> test 4
"*** Exception: Non-exhaustive patterns in function test
So, when you call any function, the runtime system will try to match
the input with the defined function. So a call to test 3 will
initially check test 1 and since 1 is not equal to 3, it will
move on to the next definition. Again since 2 is not equal to 3,
it will move to the next defintion. In the next definiton since 3 is
equal to 3 it will return "three" String back. When you try to
pattern match something, which doesn't exist at all, the program
throws the exception.

This kind of pattern matching can be transformed to a case statement (and indeed, that's what compilers will normally do!):
lucky' n = case n of
7 -> "LUCKY NUMBER SEVEN!"
x -> "Sorry, you're out of luck, pal!"
Because the x isn't really used, you'd normally write _ -> "Sorry, ..." instead.
Note that this is not2 the same as
lucky'' n = if n==7 then ...
Equality comparison with (==) is in general more expensive1 than pattern matching, and also comes out uglier.
1 Why it's more expensive: suppose we have a big data structure. To determine that they are equal, the program will need to dig through both entire structures, make sure really all branches are equal. However, if you pattern match, you will just compare a small part you're interested in right now.
2 Actually, it is the same in the case, but just because the compiler has a particular trick for pattern matching on numbers: it rewrites it with (==). This is really special for Num types and not true for anything else. (Except if you use the OverloadedStrings extension.)

That definition of lucky uses "pattern matching", and equals (in this case)
lucky :: (Integral a) => a -> String
lucky a = if a == 7
then "LUCKY NUMBER SEVEN!"
else "Sorry, you're out of luck, pal!"

I assume you're looking at learn you a haskell. After that example, it says that
When you call lucky, the patterns will be checked from top to bottom and when it conforms to a pattern, the corresponding function body will be used.
So the first line indicates the type of the function, and later lines are patterns to check. Each line has the function name so the compiler knows you're still talking about the same function.
Think of it this way: When you write the expression lucky (a+b) or whatever, the compiler will attempt to replace lucky (a+b) with the first thing before the = in the function definition that "fits." So if a=3 and b=4, you get this series of replacements:
lucky (a+b) =
lucky (3+4) =
--pattern matching occurs...
lucky 7 =
"LUCKY NUMBER SEVEN!"
This is part of what makes Haskell so easy to reason about in practice; you get a system that works similarly to math.

Related

Haskell what does the ' symbol do?

As the title states, I see pieces of code online where the variables/functions have ' next to it, what does this do/mean?
ex:
function :: [a] -> [a]
function ...
function' :: ....
The notation comes from mathematics. It is read x prime. In pretty much any math manual you can find something like let x be a number and x' be the projection of ... (math stuff).
Why not using another convention? well, in mathematics It makes a lot of sense because It can be very pedagogical... In programming we aren't used to this convention so I don't see the point of using it, but I am not against it neither.
Just to give you an example of its use in mathematics so you can understand why It is used in Haskell. Below, the same triangle concept but one using prime convention and other not using it. It is pretty clear in the first picture that pairs (A, A'), (B, B'), ... are related by one being the vertex and the prime version being the midpoint of the oposite edge. Whereas in the second example, you just have to remember that A is the midpoint of the oposite edge of vertex P. First is easier and more pedagogical:
As the other answers said, function' is just another variable name. So,
don'tUse :: Int -> IO ()
don'tUse won'tBe''used'' = return ()
is just like
dontUse :: Int -> IO ()
dontUse wontBeUsed = return ()
with slightly different names. The only requirement is that the name starts with a lowercase-letter or underscore, after that you can have as many single-quote characters as you want.
Prelude> let _' = 1
Prelude> let _'' = 2
Prelude> let _''''''''' = 9
Prelude> _' + _'' * _'''''''''
19
...Of course it's not necessarily a good idea to name variables like that; normally such prime-names are used when making a slightly different version of an already named thing. For example, foldl and foldl' are functions with the same signature that do essentially the same thing, only with different strictness (which often affects performance memory usage and whether infinite inputs are allowed, but not the actual results).
That said, to the question
Haskell what does the ' symbol do?
– the ' symbol does in fact do various other things as well, but only when it appears not as a non-leading character in a name.
'a' is a character literal.
'Foo is a constructor used on the type level. See DataKinds.
'bar and ''Baz are quoted names. See TemplateHaskell.

Haskell, make single string from integer set?

I'd greatly appreciate if you could tell me how to make a single string from a range between two ints. Like [5..10] i would need to get a "5678910". And then I'd have to calculate how many (zeroes, ones ... nines) there are in a string.
For example: if i have a range from [1..10] i'd need to print out
1 2 1 1 1 1 1 1 1 1
For now i only have a function to search for a element in string.
`countOfElem elem list = length $ filter (\x -> x == elem) list`
But the part how to construct such a string is bugging me out, or maybe there is an easier way? Thank you.
I tried something like this, but it wouldn't work.
let intList = map (read::Int->String) [15..22]
I tried something like this, but it wouldn't work. let intList = map (read::Int->String) [15..22]
Well... the purpose of read is to parse strings to read-able values. Hence it has a type signature String -> a, which obviously doesn't unify with Int -> String. What you want here is the inverse1 of read, it's called show.
Indeed map show [15..22] gives almost the result you asked for – the numbers as decimal-encoded strings – but still each number as a seperate list element, i.e. type [String] while you want only String. Well, how about asking Hoogle? It gives the function you need as the fifth hit: concat.
If you want to get fancy you can then combine the map and concat stages: both the concatMap function and the >>= operator do that. The most compact way to achieve the result: [15..22]>>=show.
1show is only the right inverse of read, to be precise.

haskell: factors of a natural number

I'm trying to write a function in Haskell that calculates all factors of a given number except itself.
The result should look something like this:
factorlist 15 => [1,3,5]
I'm new to Haskell and the whole recursion subject, which I'm pretty sure I'm suppoused to apply in this example but I don't know where or how.
My idea was to compare the given number with the first element of a list from 1 to n div2
with the mod function but somehow recursively and if the result is 0 then I add the number on a new list. (I hope this make sense)
I would appreciate any help on this matter
Here is my code until now: (it doesn't work.. but somehow to illustrate my idea)
factorList :: Int -> [Int]
factorList n |n `mod` head [1..n`div`2] == 0 = x:[]
There are several ways to handle this. But first of all, lets write a small little helper:
isFactorOf :: Integral a => a -> a -> Bool
isFactorOf x n = n `mod` x == 0
That way we can write 12 `isFactorOf` 24 and get either True or False. For the recursive part, lets assume that we use a function with two arguments: one being the number we want to factorize, the second the factor, which we're currently testing. We're only testing factors lesser or equal to n `div` 2, and this leads to:
createList n f | f <= n `div` 2 = if f `isFactorOf` n
then f : next
else next
| otherwise = []
where next = createList n (f + 1)
So if the second parameter is a factor of n, we add it onto the list and proceed, otherwise we just proceed. We do this only as long as f <= n `div` 2. Now in order to create factorList, we can simply use createList with a sufficient second parameter:
factorList n = createList n 1
The recursion is hidden in createList. As such, createList is a worker, and you could hide it in a where inside of factorList.
Note that one could easily define factorList with filter or list comprehensions:
factorList' n = filter (`isFactorOf` n) [1 .. n `div` 2]
factorList'' n = [ x | x <- [1 .. n`div` 2], x `isFactorOf` n]
But in this case you wouldn't have written the recursion yourself.
Further exercises:
Try to implement the filter function yourself.
Create another function, which returns only prime factors. You can either use your previous result and write a prime filter, or write a recursive function which generates them directly (latter is faster).
#Zeta's answer is interesting. But if you're new to Haskell like I am, you may want a "simple" answer to start with. (Just to get the basic recursion pattern...and to understand the indenting, and things like that.)
I'm not going to divide anything by 2 and I will include the number itself. So factorlist 15 => [1,3,5,15] in my example:
factorList :: Int -> [Int]
factorList value = factorsGreaterOrEqual 1
where
factorsGreaterOrEqual test
| (test == value) = [value]
| (value `mod` test == 0) = test : restOfFactors
| otherwise = restOfFactors
where restOfFactors = factorsGreaterOrEqual (test + 1)
The first line is the type signature, which you already knew about. The type signature doesn't have to live right next to the list of pattern definitions for a function, (though the patterns themselves need to be all together on sequential lines).
Then factorList is defined in terms of a helper function. This helper function is defined in a where clause...that means it is local and has access to the value parameter. Were we to define factorsGreaterOrEqual globally, then it would need two parameters as value would not be in scope, e.g.
factorsGreaterOrEqual 4 15 => [5,15]
You might argue that factorsGreaterOrEqual is a useful function in its own right. Maybe it is, maybe it isn't. But in this case we're going to say it isn't of general use besides to help us define factorList...so using the where clause and picking up value implicitly is cleaner.
The indentation rules of Haskell are (to my tastes) weird, but here they are summarized. I'm indenting with two spaces here because it grows too far right if you use 4.
Having a list of boolean tests with that pipe character in front are called "guards" in Haskell. I simply establish the terminal condition as being when the test hits the value; so factorsGreaterOrEqual N = [N] if we were doing a call to factorList N. Then we decide whether to concatenate the test number into the list by whether dividing the value by it has no remainder. (otherwise is a Haskell keyword, kind of like default in C-like switch statements for the fall-through case)
Showing another level of nesting and another implicit parameter demonstration, I added a where clause to locally define a function called restOfFactors. There is no need to pass test as a parameter to restOfFactors because it lives "in the scope" of factorsGreaterOrEqual...and as that lives in the scope of factorList then value is available as well.

Correct way to define a function in Haskell

I'm new to Haskell and I'm trying out a few tutorials.
I wrote this script:
lucky::(Integral a)=> a-> String
lucky 7 = "LUCKY NUMBER 7"
lucky x = "Bad luck"
I saved this as lucky.hs and ran it in the interpreter and it works fine.
But I am unsure about function definitions. It seems from the little I have read that I could equally define the function lucky as follows (function name is lucky2):
lucky2::(Integral a)=> a-> String
lucky2 x=(if x== 7 then "LUCKY NUMBER 7" else "Bad luck")
Both seem to work equally well. Clearly function lucky is clearer to read but is the lucky2 a correct way to write a function?
They are both correct. Arguably, the first one is more idiomatic Haskell because it uses its very important feature called pattern matching. In this form, it would usually be written as:
lucky::(Integral a)=> a-> String
lucky 7 = "LUCKY NUMBER 7"
lucky _ = "Bad luck"
The underscore signifies the fact that you are ignoring the exact form (value) of your parameter. You only care that it is different than 7, which was the pattern captured by your previous declaration.
The importance of pattern matching is best illustrated by function that operates on more complicated data, such as lists. If you were to write a function that computes a length of list, for example, you would likely start by providing a variant for empty lists:
len [] = 0
The [] clause is a pattern, which is set to match empty lists. Empty lists obviously have length of 0, so that's what we are having our function return.
The other part of len would be the following:
len (x:xs) = 1 + len xs
Here, you are matching on the pattern (x:xs). Colon : is the so-called cons operator: it is appending a value to list. An expression x:xs is therefore a pattern which matches some element (x) being appended to some list (xs). As a whole, it matches a list which has at least one element, since xs can also be an empty list ([]).
This second definition of len is also pretty straightforward. You compute the length of remaining list (len xs) and at 1 to it, which corresponds to the first element (x).
(The usual way to write the above definition would be:
len (_:xs) = 1 + len xs
which again signifies that you do not care what the first element is, only that it exists).
A 3rd way to write this would be using guards:
lucky n
| n == 7 = "lucky"
| otherwise = "unlucky"
There is no reason to be confused about that. There is always more than 1 way to do it. Note that this would be true even if there were no pattern matching or guards and you had to use the if.
All of the forms we've covered so far use so-called syntactic sugar provided by Haskell. Pattern guards are transformed to ordinary case expressions, as well as multiple function clauses and if expressions. Hence the most low-level, unsugared way to write this would be perhaps:
lucky n = case n of
7 -> "lucky"
_ -> "unlucky"
While it is good that you check for idiomatic ways I'd recommend to a beginner that he uses whatever works for him best, whatever he understands best. For example, if one does (not yet) understand points free style, there is no reason to force it. It will come to you sooner or later.

Why doesn't my Haskell function accept negative numbers?

I am fairly new to Haskell but do get most of the basics. However there is one thing that I just cannot figure out. Consider my example below:
example :: Int -> Int
example (n+1) = .....
The (n+1) part of this example somehow prevents the input of negative numbers but I cannot understand how. For example.. If the input were (-5) I would expect n to just be (-6) since (-6 + 1) is (-5). The output when testing is as follows:
Program error: pattern match failure: example (-5)
Can anyone explain to me why this does not accept negative numbers?
That's just how n+k patterns are defined to work:
Matching an n+k pattern (where n is a variable and k is a positive integer literal) against a value v succeeds if x >= k, resulting in the binding of n to x - k, and fails otherwise.
The point of n+k patterns is to perform induction, so you need to complete the example with a base case (k-1, or 0 in this case), and decide whether a parameter less than that would be an error or not. Like this:
example (n+1) = ...
example 0 = ...
The semantics that you're essentially asking for would be fairly pointless and redundant — you could just say
example n = let n' = n-1 in ...
to achieve the same effect. The point of a pattern is to fail sometimes.

Resources