[Haskell-beginners] Are these soloutions all valid and a good use of Haskell
Roelof Wobben
r.wobben at home.nl
Mon Nov 10 15:10:37 UTC 2014
No problem .
Im strugelling to make acc work.
I try to say that if the input list has only 1 item the outcome is the
head of that list.
But doing
acc = Just (head a) or doing acc = Just (head acc) gives both that acc
or a is not in scope
also doing acc x = Just (head x) gives a error messages that the types
are not matching.
Roelof
Stefan Höck schreef op 10-11-2014 15:23:
> Just a quick note: That's 'typed holes' not 'type holes' ...
>
> On Mon, Nov 10, 2014 at 03:12:20PM +0100, Stefan Höck wrote:
>> Hi Roelof
>>
>> It seems like you try to do too many things at once. Here's how you
>> could go about this step-by-step and let GHC help you implement your
>> functions along the way:
>>
>> First, give the type signature of your function:
>>
>> last5 :: [a] -> Maybe a
>> last5 = undefined
>>
>> Now, load this into GHCi or compile with GHC. If it compiles, you're
>> on the right track. Now, you want to implement it using a fold
>> (try both, foldl and foldr):
>>
>> last5 :: [a] -> Maybe a
>> last5 xs = foldr _ _ xs
>>
>> The underscores are 'type holes'. This tells the compiler to give you
>> some information about what is supposed to be placed at the two
>> positions. For the moment, we are only interested in the types of the
>> things that go there. The compiler will tell you, that
>> the hole at the first position is of type
>>
>> a -> Maybe a -> Maybe a
>>
>> and the hole at the second position is of type
>>
>> Maybe a
>>
>> Now, instead of filling the holes in place, let's define two helper
>> functions together with their type signatures. You can later on inline
>> them in your definition of last5, but for the time being, let's get as
>> much help from the compiler as we can.
>>
>> last5 :: [a] -> Maybe a
>> last5 xs = foldr acc initial xs
>>
>> acc :: a -> Maybe a -> Maybe a
>> acc = undefined
>>
>> initial :: Maybe a
>> initial = undefined
>>
>> Again, compile or load into GHCi. If you did anything wrong, the
>> compiler will tell you so. There is only one possible way to
>> implement function `initial` without cheating (= raising an error)
>>
>> initial :: Maybe a
>> initial = Nothing
>>
>> Function `acc` can be implemented in several ways. Only one of them
>> will lead to the desired behavior. Finding out the proper implementation
>> is the main point of this folding-exercise. Try also an implementation
>> using foldl. Does it behave as expected? What are the differences
>> compared to foldr? When you feed your implementations a huge list -
>> say [1..20000000] - what happens?
>>
>> Note that whenever you get an error message in a rather complex
>> function implementation, move local function definitions and lambdas
>> to the top level, give them a type signature and implement them
>> separately one at a time. Use type holes to let the compiler give
>> assistance with type signatures and possible implementations.
>> Once everything compiles and runs as expected, move the toplevel
>> definitions back to where you'd like them best.
>>
>> Stefan
>>
>> PS: A more succint implementation of last5 would use currying:
>>
>> last5 = foldr acc initial
>>
>> PPS: If you get a stack overflow with very large lists, try
>> using foldl' from Data.List (or better, once you learned
>> about the Foldable type class, from Data.Foldable).
>>
>> On Mon, Nov 10, 2014 at 02:28:08PM +0100, Roelof Wobben wrote:
>>> I tried and so far I have this :
>>>
>>> last5 = foldl(\acc x -> if x=[] then x else acc xs) [] xs
>>>
>>> But now I get parse error on the -> part.
>>>
>>> Roelof
>>>
>>>
>>> Roelof Wobben schreef op 10-11-2014 13:47:
>>>> Thanks all,
>>>>
>>>> I will try to make a fold solution as soon as I see that functional
>>>> explained in the learnyouahaskell.
>>>>
>>>> Roelof
>>>>
>>>>
>>>> Frerich Raabe schreef op 10-11-2014 11:43:
>>>>> On 2014-11-10 11:16, Karl Voelker wrote:
>>>>>> On Mon, Nov 10, 2014, at 01:50 AM, Roelof Wobben wrote:
>>>>>>> What do you experts think of the different ways ?
>>>>>> 2 and 4 are quite similar, and both fine. 3 is not so good: guards
>>>>>> provide weaker guarantees than patterns, and head and tail are partial
>>>>>> functions.
>>>>> In addition to what Karl wrote, I'd like to suggest not using the
>>>>> semicolon all the time -- it's not needed and just adds noise.
>>>>>
>>>>>> All three implementations have in common that they do their own
>>>>>> recursion. It would be a good exercise to try implementing last as a
>>>>>> fold - in other words, letting the standard library do the recursion
>>>>>> for
>>>>>> you.
>>>>> Right - I suggest trying to express the problem with the most abstract
>>>>> function first, then consider using a fold, then use manual recursion.
>>>>> in
>>>>> your particular case you could exploit that for non-empty lists, getting
>>>>> the last element of a list is the same as getting the first element of
>>>>> a reversed list (and there are ready-made functions for reversing a list
>>>>> and getting the first element of a list).
>>>>>
>>>> _______________________________________________
>>>> Beginners mailing list
>>>> Beginners at haskell.org
>>>> http://www.haskell.org/mailman/listinfo/beginners
>>>>
>>> _______________________________________________
>>> Beginners mailing list
>>> Beginners at haskell.org
>>> http://www.haskell.org/mailman/listinfo/beginners
>>>
> _______________________________________________
> Beginners mailing list
> Beginners at haskell.org
> http://www.haskell.org/mailman/listinfo/beginners
>
More information about the Beginners
mailing list