Haskell - Putting out result of function

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4

46 Replies - 4714 Views - Last Post: 24 July 2016 - 11:47 AM

#31 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 16 July 2016 - 03:05 PM

I'm having hard troubles with understanding the Let, Monads, and especially those types. When I search them up and view the examples, I understand those. But I can't seem to implement it in my own applications.

I feel very limited with those strict type errors and crazy rules; in imperative languages I feel more freedom...

import Data.List
import Data.Maybe

myList = do
    let x = "d"
    let lst = ["a", "b", "c", x]
    lst ++ ["e"]

excludedList = [1..10]
f::Int -> Maybe Int
f x =
    if x `elem` excludedList
        then Nothing
    else Just x

deleteAtIndex :: Int -> [a] -> [a]
deleteAtIndex i lst = do
    let z = splitAt (i + 1) lst
        x = init $ fst z
        y = snd z

    x ++ y

insertAtIndex :: Int -> [a] -> [a] -> [a]
insertAtIndex i lst s = do
    let z = splitAt (i + 1) lst
       	x = (fst z) ++ s
        y = snd z
    
    x ++ y

------------------------------------------------
replaceAtIndex :: Eq a => a -> [a] -> [a] -> [a]
replaceAtIndex toReplace lst newNmr = do
    let i = elemIndex toReplace lst
	    
    case i of
        Just i ->
        {-
            let z = splitAt i lst in z
            let x = fst z in x
            let y = snd z in y
          -}
            let z = splitAt i lst
                x = fst z
                y = snd z
                in do
                    init $ fst x
                    x ++ newNmr
                    x ++ y
            
        Nothing -> Nothing 
    
    {-
    init $ fst x
    x ++ newNmr
    x ++ y
    -}

main = do
    putStrLn $ show myList
    putStrLn $ show $ f 15

    let anotherList = ["a", "b", "c", "d"]
    putStr $ unlines anotherList
    mapM putStr anotherList

    putStrLn "\n\n\n\n\n"

    putStr $ unlines myList

    putStrLn "\n\n\n\n\n"

    let testLst1 = [1..25]
    putStrLn $ show $ deleteAtIndex 10 testLst1
    putStrLn $ show $ insertAtIndex 15 testLst1 [12345]
    putStrLn $ show $ replaceAtIndex 5 testLst1 [3]




Error:

Quote

C:\users\niel\desktop\test2.hs:48:32: error:
* Couldn't match expected type `([a0], b0)' with actual type `[a]'
* In the first argument of `fst', namely `x'
In the second argument of `($)', namely `fst x'
In a stmt of a 'do' block: init $ fst x
* Relevant bindings include
y :: [a] (bound at C:\users\niel\desktop\test2.hs:46:17)
x :: [a] (bound at C:\users\niel\desktop\test2.hs:45:17)
z :: ([a], [a]) (bound at C:\users\niel\desktop\test2.hs:44:17)
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)

C:\users\niel\desktop\test2.hs:52:20: error:
* Couldn't match expected type `[a]' with actual type `Maybe a1'
* In the expression: Nothing
In a case alternative: Nothing -> Nothing
In a stmt of a 'do' block:
case i of {
Just i
-> let
z = ...
....
in
do { init $ fst x;
.... }
Nothing -> Nothing }
* Relevant bindings include
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
replaceAtIndex :: a -> [a] -> [a] -> [a]
(bound at C:\users\niel\desktop\test2.hs:34:1)

Was This Post Helpful? 0
  • +
  • -

#32 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 16 July 2016 - 03:59 PM

View PostO, on 17 July 2016 - 12:05 AM, said:

I feel very limited with those strict type errors and crazy rules; in imperative languages I feel more freedom...



Except for the mixing of IO and non-IO code (which was only an issue once in this thread), I don't think the strict typing is your problem here. Like in an imperative language you might not get an error for writing code like this (though that depends on the language):

String str = "hello";
str + "goodbye";
return str;



Yet it still won't do what you wanted it to do, so if anything I'd say the strict errors were helpful as they brought attention to a logical error. And for example returning different types in different branches is also an error in imperative languages (statically typed ones anyway).

Quote

Error:

Quote

C:\users\niel\desktop\test2.hs:48:32: error:
* Couldn't match expected type `([a0], b0)' with actual type `[a]'
* In the first argument of `fst', namely `x'


fst takes a tuple, not a list.


Quote

C:\users\niel\desktop\test2.hs:52:20: error:
* Couldn't match expected type `[a]' with actual type `Maybe a1'
* In the expression: Nothing


Again all branches need to return the same type. In one of the cases of your pattern match you return a list, but in the other a Maybe (Nothing). You probably want to return Just theList in the case where you return the list.

Also note that you're still using ++ as if it changed the value of the list.

This post has been edited by sepp2k: 16 July 2016 - 03:59 PM

Was This Post Helpful? 0
  • +
  • -

#33 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 08:11 AM

I understand what you mean, but again, can't implement it.

Quote

fst takes a tuple, not a list.

So I use the !! operator? Right?

            let z = splitAt i lst
                x = z !! 0
                y = z !! 1
                in do
                    init $ x !! 0
                    x ++ newNmr
                    x ++ y




The problem is, that I get this error:

Quote

C:\users\niel\desktop\test2.hs:45:21: error:
* Couldn't match expected type `[a1]' with actual type `([a], [a])'
* In the first argument of `(!!)', namely `z'
In the expression: z !! 0
In an equation for `x': x = z !! 0
* Relevant bindings include
x :: a1 (bound at C:\users\niel\desktop\test2.hs:45:17)
z :: ([a], [a]) (bound at C:\users\niel\desktop\test2.hs:44:17)
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
replaceAtIndex :: a -> [a] -> [a] -> [a]
(bound at C:\users\niel\desktop\test2.hs:34:1)

C:\users\niel\desktop\test2.hs:46:21: error:
* Couldn't match expected type `[a1]' with actual type `([a], [a])'
* In the first argument of `(!!)', namely `z'
In the expression: z !! 1
In an equation for `y': y = z !! 1
* Relevant bindings include
y :: a1 (bound at C:\users\niel\desktop\test2.hs:46:17)
z :: ([a], [a]) (bound at C:\users\niel\desktop\test2.hs:44:17)
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
replaceAtIndex :: a -> [a] -> [a] -> [a]
(bound at C:\users\niel\desktop\test2.hs:34:1)


Quote

Again all branches need to return the same type. In one of the cases of your pattern match you return a list, but in the other a Maybe (Nothing). You probably want to return Just theList in the case where you return the list.


How'd I do this than?
            let z = splitAt i lst
                x = z !! 0
                y = z !! 1
                in do
                    init $ fst x
                    x ++ newNmr
                    x ++ y
            




I can't just set it above the case, because that'd give errors due to i.

Quote

Also note that you're still using ++ as if it changed the value of the list.

The problem is, the last line in a do must be an expression. How'd I do that than?
let x = x ++ y
ain't an expression. And Haskell doesn't have to return-keyword like there is in other languages.


Edit:
I managed to fix the error with the !!-operator myself.
The type was: ([a], [a])
So, a list in a tuple. So this is how I needed to combine fst for tuple and !! for list:
            let z = splitAt i lst
                x = (fst z) !! 0
                y = (fst z) !! 1
                in do
                    init $ x !! 0
                    x ++ newNmr
                    x ++ y




Only this error is remaining:

Quote

C:\users\niel\desktop\test2.hs:52:20: error:
* Couldn't match expected type `[a]' with actual type `Maybe a1'
* In the expression: Nothing
In a case alternative: Nothing -> Nothing
In a stmt of a 'do' block:
case i of {
Just i
-> let
z = ...
....
in
do { init $ x !! 0;
.... }
Nothing -> Nothing }
* Relevant bindings include
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
replaceAtIndex :: a -> [a] -> [a] -> [a]
(bound at C:\users\niel\desktop\test2.hs:34:1)


And I don't know how to do ++ to change the list, and to make the do-block end with an expression.

This post has been edited by O'Niel: 19 July 2016 - 08:17 AM

Was This Post Helpful? 0
  • +
  • -

#34 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 11:37 AM

You can't change the list. All you can do is produce a new list with the desired elements. And as I said, you should really get rid of the do-block altogether. You can't make it do what you want and it just seems to be confusing you.
Was This Post Helpful? 0
  • +
  • -

#35 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 11:48 AM

Okay, I now got rid of the two DOs, but the problem now is that I need 'in' for all my 'let'. I understand the let in this example:
http://zvon.org/othe..._reference.html

You declare the variables on which you'll perform calculations on after your 'in'.
However, I won't know how I'd do it in Haskell.

Can't I just make a function with variables in it (not meaning parameters).
Was This Post Helpful? 0
  • +
  • -

#36 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 11:56 AM

You can make a function with variables in it using let (with in) or where. For example if your function in imperative syntax would look like this:

String foo(String a, String B)/> {
    String c = a + "bla";
    String d = b + "blubb";
    return c + d;
}



Then the Haskell version would look like this:

foo :: String -> String -> String
foo a b =
  let c = a ++ "bla"
      d = b ++ "blubb"
  in  c ++ d



or:

foo :: String -> String -> String
foo a b = c ++ d
  where
    c = a ++ "bla"
    d = b ++ "blubb"


Was This Post Helpful? 0
  • +
  • -

#37 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 12:07 PM

Ain't that exactly what I have? But then with three lines in the 'in'?
    let i = elemIndex toReplace lst in
	    
        case i of
            Just i ->
                let z = splitAt i lst
                    x = (fst z) !! 0
                    y = (snd z) !! 0
                    in
                        init $ x !! 0
                        x ++ newNmr
                        x ++ y
                
            Nothing -> Nothing 




Error:

Quote

C:\users\niel\desktop\test2.hs:44:30: error:
* Couldn't match expected type `a -> [a]' with actual type `[a]'
* The function `newNmr' is applied to one argument,
but its type `[a]' has none
In the first argument of `(++)', namely `newNmr x'
In the second argument of `(++)', namely `newNmr x ++ y'
* Relevant bindings include
y :: a (bound at C:\users\niel\desktop\test2.hs:41:21)
x :: a (bound at C:\users\niel\desktop\test2.hs:40:21)
z :: ([a], [a]) (bound at C:\users\niel\desktop\test2.hs:39:21)
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
(Some bindings suppressed; use -fmax-relevant-binds=N or -fno-max-relevant-binds)

C:\users\niel\desktop\test2.hs:47:24: error:
* Couldn't match expected type `[a]' with actual type `Maybe a0'
* In the expression: Nothing
In a case alternative: Nothing -> Nothing
In the expression:
case i of {
Just i
-> let
z = ...
....
in init $ x !! 0 x ++ newNmr x ++ y
Nothing -> Nothing }
* Relevant bindings include
newNmr :: [a] (bound at C:\users\niel\desktop\test2.hs:34:30)
lst :: [a] (bound at C:\users\niel\desktop\test2.hs:34:26)
toReplace :: a (bound at C:\users\niel\desktop\test2.hs:34:16)
replaceAtIndex :: a -> [a] -> [a] -> [a]
(bound at C:\users\niel\desktop\test2.hs:34:1)


I really don't have a clue...
Was This Post Helpful? 0
  • +
  • -

#38 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 02:23 PM

You can only have one expression after the in. And even if you could have more than one expression, what would you expect the result to be? As I said, none of the expressions have any side-effects (and if they did, they'd have to be of type IO), so if you don't use their result by returning it or storing it in a variable, there's no point to having the expression at all.
Was This Post Helpful? 0
  • +
  • -

#39 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 03:22 PM

Could you please help me to build the replaceAtIndex function again?
For me it's really a dead trail...

In imperative (e.g Python) I'd do this:
def replaceAtIndex(toReplace, lst, newNmr):
    for i in range(0, len(lst)):
        if lst[i] == toReplace:
            lst[i] = newNmr
    
    return lst

testLst1 = list(range(0, 25+1))

print(testLst1)
print(replaceAtIndex(5, testLst1, 3))




How'd I do this in Haskell?
Was This Post Helpful? 0
  • +
  • -

#40 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 19 July 2016 - 04:05 PM

I'd write it like this:

replaceInList Eq a => a -> a -> [a]
replaceInList oldValue newValue xs = map replaceItem xs
  where
    replaceItem x =
      if x == oldValue
      then newValue
      else x


Here I define a local function replace, which takes a single value and then either returns the value unchanged or returns newValue depending on whether or not the given value is equal to oldValue. I then apply this function to every element in the list with map.

PS: replaceAtIndex is a rather misleading name for your function as it has nothing to do with indices. I'd also like to point out that your Python function changes its argument in place, but also returns a reference to it, which can be somewhat confusing. The Haskell version of course does not mutate anything.
Was This Post Helpful? 1
  • +
  • -

#41 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 20 July 2016 - 03:51 PM

Okay, I think I got it.

This is my working code:
replaceInList :: Eq a => a -> a -> [a] -> [a]
replaceInList oldVal newVal lst = map replaceItem lst
    where
        replaceItem x =
            if x == oldVal
                then newVal
            else x

putStrLn $ show $ replaceInList 5 3 testLst1



Output:

Quote

[1,2,3,4,3,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]


Explanation:
Eq a => This is to say that our function parameters only allow the type `a` with the class Eq. Which is the equal-class (==). This way only type A's for equality-testing are allowed. This is a part of the type-signature. And `a`can be of any type as long as it is the same type as the `a` in `[a]`.

map x y map is a function which performs a specific function (the x-parameter) on every element in list `y`.
So map (2*) [1,2,3] returns: [2,4,6].
In this case the first parameter is the function replaceItem, and the second parameter `lst`, this way we trigger replaceItem for every element in `lst`.

where With where we define the value of variables, or functions we used in the previous expression. In this case we define the function replaceItem with a parameter. This parameter is an element of our list, but because we used map, this is like a kind of loop for every element in our list.

In replaceItem we check if a element equals the given element (oldVal), if it does it gets somehow replaced with newVal. I don't see how it's replaced because you just say, then newValue, I'd rather expect something like: then x = newValue.

Is this all correct?

This post has been edited by O'Niel: 20 July 2016 - 03:52 PM

Was This Post Helpful? 0
  • +
  • -

#42 sepp2k  Icon User is offline

  • D.I.C Lover
  • member icon

Reputation: 2517
  • View blog
  • Posts: 4,001
  • Joined: 21-June 11

Re: Haskell - Putting out result of function

Posted 20 July 2016 - 04:37 PM

View PostO, on 21 July 2016 - 12:51 AM, said:

In replaceItem we check if a element equals the given element (oldVal), if it does it gets somehow replaced with newVal. I don't see how it's replaced because you just say, then newValue, I'd rather expect something like: then x = newValue.


There's no replacement in the sense you're thinking. As I mentioned previously, there are no side effects outside of the IO monad and variables can't be re-assigned at all. What the replace function does is to either return newValue or x. The Python equivalent would be this:

def replaceInList(oldVal, newVal, lst):
  def replaceItem(x):
    if x == oldVal:
      return newVal
    else:
      return oldVal

  return [replaceItem(x) for x in lst]
  # or closer to my Haskell code:
  # return map(replaceItem, lst)



So all the replaceItem function does is to return a value. map then uses that value to populate the new list. Nothing is mutated. Nothing is ever mutated.

To understand why that is desirable (and enforced by Haskell), you can compare the Python function I wrote above with the one you posted, specifically what happens to testLst1 after you call the function on it.

Quote

Is this all correct?


Yes, except for the above mentioned, everything you said is correct.
Was This Post Helpful? 1
  • +
  • -

#43 baavgai  Icon User is offline

  • Dreaming Coder
  • member icon


Reputation: 6996
  • View blog
  • Posts: 14,635
  • Joined: 16-October 07

Re: Haskell - Putting out result of function

Posted 21 July 2016 - 05:33 AM

Some folks enjoy the game of avoiding if then in haskell.

Note, you can write replaceItem like so:
replaceItem oldVal newVal xs = map f xs
    where f x | x == oldVal = newVal | otherwise = x 


This is simply the standard guards syntax.

Alternately, rather than map, you can roll your own recursion. One way:
replaceItem :: Eq a => a -> a -> [a] -> [a]
replaceItem _ _ [] = []
replaceItem oldVal newVal (x:xs) =
    (if x == oldVal then newVal else x) : replaceItem oldVal newVal xs



As it's vital you understand recursion in haskell, I'd be exploring that.

For instance, what if you wanted to just replace the first occurrence? A recursive solution is pretty straight forward:
replaceFirst :: Eq a => a -> a -> [a] -> [a]
replaceFirst oldVal newVal xs = loop xs
    where
        loop (y:ys)
            | y == oldVal = newVal : ys
            | otherwise = y : loop ys
        loop [] = []



As a did a quick mental refresh of haskell syntax, I feel I should point out that this is quite a good book: http://learnyouahask...om/introduction

Hope this helps.
Was This Post Helpful? 1
  • +
  • -

#44 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 21 July 2016 - 01:08 PM

Thanks. I'll look into recursion now, however, avoiding if/else is still a step to far for me IMHO. ;)
Thanks for your suggestions!
Was This Post Helpful? 0
  • +
  • -

#45 O'Niel  Icon User is offline

  • D.I.C Regular

Reputation: 14
  • View blog
  • Posts: 389
  • Joined: 13-September 15

Re: Haskell - Putting out result of function

Posted 22 July 2016 - 01:45 PM

Okay, so recursion. I took a look at it, read about it, and think I got the basics of it.
I chose the function maximum for this example, because it's the easiest IMHO.

In Imperative:
def maximum(lst):
    #Edge-conditions
    if len(lst) == 1:
        return lst[0]
    if len(lst) < 1:
        return "Error"

    #The loop (recursion in Haskell)
    for i in range(0, len(lst)):
        max =  lst[0]
        if lst[i] > max:
            max = lst[i]

        return max

print ( maximum([5]) )
print ( maximum([]) )
print ( maximum([1, 5, 2]) )



(I made the maximum-function longer then needed by intention, to convert it easier to Haskell).

What we do here first, is checking if the given list only has one element. If it is so, we return that element, because he's the biggest, cause he's alone...
Then we check if the list ain't empty, if it is empty, we return an error.

If it ain't any of those 'patterns' (is that the right term? Also in imperative?) then we launch the for loop.
Simply, if an element is bigger then the previous element, that element is the biggest. Save that in a variable and return it on finish.

Now,
the working Haskell-code:
maximum' :: (Ord a) => [a] -> a
maximum' [] = error "Empty list doesn't have a max!"
maximum' [x] = x
maximum' (x:xs)
    | x > maximumInTail = x
    | otherwise = maximumInTail
    where maximumInTail = maximum' xs

main = do
    print $ maximum' [5]
    --putStrLn $ maximum' []
    putStrLn $ show $ maximum' [1, 5, 2] 



(Line 11 commented out, because that of course would cause an error, by intention).

First at line 1:
I set the type signature for the maximum' function. We only allow type a's (all types) and say they belong to the class Ord, which is Ordered. That's to allow comparing (<=, >, <,...).

I use an apostrophe (') to not interfere with an a maybe already existing function called maximum.
The function takes a list of all types, and returns an element of that type. So if [a] would be an int we'd get an int: [Int] -> Int & [String] -> String,...

Then, on line 2:
I set my first pattern. Which says that if the given argument for maximum is an empty list, we return a 'custom' error-message. We can create custom error-messages using the error-keyword.
We do this because empty-lists of course can't contain a maximum. You can't be the biggest if you don't exist..

On line 3:
You have my second pattern. Which says that if my list has only one element, we should return that element because it logically is the biggest.

Then, line 4:
You see my third pattern, which is where the actual action begins, if none of the patterns above are matched.
The first complex thing I see is (x:xs).

Well, I think it is this.
It is kind of a function, but also a kind of argument.
A function because it turns [1, 5, 2] into 1 [5, 2],
and an argument because it's after the function-name and it holds the value x and xs.

I think xs is just a Haskell-thing of naming lists. xs is a list of elements with type x. x is such an element with that type. Like a and [a], we now have x and xs in arguments.

And this is how the function works.
A) The input is [1, 5, 2],
B ) because of (x:xs) it gets turned into 1 [5, 2]
C) Now we check which is the biggest, 1 (x) or maximumInTail,
D) We say (with the where-keyword) that maximumInTail is actually the function maximum' with parameter xs,
xs is in this case [5, 2]
E) So, we automatically 'loop' back to the first pattern at line 2,
F) We check if it matches any of the first two patterns, it doesn't so we launch the third pattern.
G) Because of (x:xs) our argument ([5, 2]) gets split into 5 [2],
It checks again which is the biggest, we launch the maximum' function again via the where-keyword and maximumInTail, and again loop back to the first pattern.
H) However, in this case our argument is [2], and matches the second pattern at line 3! So we get 2 returned.
I) And now we go steps-back. The x-argument has held the integers 1 (at step 1) and 5 (at step 2). We were, at step 3 and go back one step, to step 2.
Step 3 had 2, and step 2 had 5. So step 2 wins.
Than, step 2 (5) vs step 1 (1), step 2 wins.
So Step 2 is the winner,
and cause of that 5 is the maximum in our list. Right?

And would someone bother to explain me what those | at line 5 and 6 are?
I researched it and found an answer (by coincidence, also from you (sepp2k) at SO) that it had to do with functional dependencies. When I researched that, I found something about restricting function parameters, and that one can determine the value of another parameter. And return a parameter, which not necessary needs the type of the function??? I didn't got that.

I just interpret it as:
We use the vertical bars at line 5 and 6, that way these get wrapped.
They need to be wrapped because they share the same 'variable'/'function' called maximumInTail, however, in other expressions and yet undeclared.
Because we wrapped 5 and 6, the where-keyword defines the name maximumInTail for line 5 and 6.

However, would someone explain me what those vertical bars are?

And another thing,
Why won't print work at line 12? Because it's the same as
putStrLn $ show $, and the show ('converting' to string) causes an error?

This post has been edited by O'Niel: 22 July 2016 - 01:47 PM

Was This Post Helpful? 0
  • +
  • -

  • (4 Pages)
  • +
  • 1
  • 2
  • 3
  • 4