0.14 to 0.15 code changes

183 views
Skip to first unread message

Bryan Muir

unread,
Apr 20, 2015, 3:12:40 PM4/20/15
to elm-d...@googlegroups.com
The following code worked in 0.14 in the online editor and using elm-make, but I can't seem to get it to work in 0.15.

Can someone point out what I'm doing wrong?


-- 0.14 imports

--import List (..)

--import Basics (..)


import List exposing (..)

import Basics exposing (..)


fibonacci : Int -> List Int

fibonacci n =

    let fibonacci' n acc =

        if n <= 2

            then acc

            else fibonacci' (n-1) ((head acc + (tail >> head) acc) :: acc)

    in

        fibonacci' n [1,1] |> reverse


fibonacciWithIndexes : Int -> List (Int, Int)

fibonacciWithIndexes n = map2 (,) [0..n] (fibonacci n)

Hassan Hayat

unread,
Apr 20, 2015, 3:15:57 PM4/20/15
to elm-d...@googlegroups.com
head and tail have different types.

For example: 

head : List a -> Maybe a

instead of just returning a. So, you'll have to sprinkle some filtering. Maybe.withDefault is your friend here.

Evan Czaplicki

unread,
Apr 20, 2015, 3:37:32 PM4/20/15
to elm-d...@googlegroups.com
I found my code with head and tail was the most difficult to upgrade by far. I did a refactor of your code to update it, and I think it's actually a nice argument for making the change to head/tail that we did:

import Graphics.Element exposing (show)


fibonacci : Int -> List Int
fibonacci goal =
    let fibonacciHelp n a b fibs =
        if n >= goal
            then List.reverse fibs
            else fibonacciHelp (n+1) (a + b) a (a :: fibs)
    in
        fibonacciHelp 0 1 0 []


fibonacciWithIndexes : Int -> List (Int, Int)
fibonacciWithIndexes n =
    List.map2 (,) [0..n] (fibonacci n)
 

main = show (fibonacciWithIndexes 15)


To me, the fibonacciHelp function is a bit clearer about exactly what is going on. It is also 100% crash free no matter what.

Does that help?

--
You received this message because you are subscribed to the Google Groups "Elm Discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to elm-discuss...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

Bryan Muir

unread,
Apr 20, 2015, 4:09:23 PM4/20/15
to elm-d...@googlegroups.com
It should help once I wrap my brain around it.  

This functional programming is still real new here, so I end up walking through the steps of recursion with a pencil and paper to make sure my brain follows what is going on.

Given enough paper and some alcohol to loosen the straight jacket imperative programming wrapped around my brain and  I'm sure the light will dawn and I will grok it...

Thanks

Evan Czaplicki

unread,
Apr 20, 2015, 4:31:10 PM4/20/15
to elm-d...@googlegroups.com
Haha, no problem :)

I think the "expand it out a couple levels" is a great strategy for getting your brain out of for-loop mode. I definitely did this a ton when trying to figure out what the heck was going on with foldl/foldr back when I was learning Scheme as my first functional language :) In any case, let us know if we can help with anything, we are always happy to help!

Max Goldstein

unread,
Apr 20, 2015, 10:26:25 PM4/20/15
to elm-d...@googlegroups.com
Hi Bryan,

The "expand it out" strategy can be helpful, but let me suggest something that may be even better. Think about the contract (pre and postconditions) of the function, writing it down if necessary. Then replace the recursive call with what the contract says that call should mean. If you're familiar with proofs by induction, think about the inductive step. Or think about trusting an interface in code, except that interface is with yourself.

Bryan Muir

unread,
Apr 21, 2015, 11:17:32 AM4/21/15
to elm-d...@googlegroups.com
ok, so I ran across an online book called Elm by Example (can be found here) and I have been working through the examples with Elm 0.15.  Yes, I know it was written using a different version of Elm. But the examples looked pretty simple, so I thought I could fix the errors and learn more about Elm a the same time.

This thread started when I couldn't figure out how to get the Fibonacci function from the book to quit throwing errors.  Evan was kind enough to provide a re-written example that makes sense and also eliminated the errors.

Hassan mentioned that Maybe.withDefaults could be used to add filtering and help avoid the errors I received.

So when I went to the next part of the sample, I once again received some errors that I don't understand. I'll try and explain where my thought process is going awry, so maybe someone can set me straight.

The program uses a function to grab a color from a list based on an index that is passed in.  The function looks like so...

barColor : Int -> Color

barColor n =

    let colors = [ red, orange, yellow, green, blue, purple, brown ]

    in

        drop (n % (length colors)) colors |> head


My understanding of this is..   Take the index we want and mod by the length of the list, mod returns the remainder (or the number to drop to get the entry we want).  This is passed to the drop command which returns a list with our requested index being at the head., so we pass it to the head function and head returns the color at the top of the list.

Seems simple enough, except that head doesn't return the top entry as a color, it returns it as a Maybe.Maybe Color.Color.

The error from elm-make is...

Type mismatch between the following types between lines 13 and 15:


        Color.Color


        Maybe.Maybe Color.Color


    It is related to the following expression:


        let colors = [red,orange,yellow,green,blue,purple,brown]

        in (drop (n % (length colors)) colors) |> head



So my question is this...    if I am expecting a Color.Color to be returned, what do I need to add/change in this code to take the returned Maybe.Maybe into account?  I assume that since the signature of head is..


<function> : List a -> Maybe.Maybe a


that this is something I am going to run into every time I use head, so I may as well try and get this straight in my head now (twisted head reference intended).


Thanks,


Bryan


Max Goldstein

unread,
Apr 21, 2015, 12:26:32 PM4/21/15
to elm-d...@googlegroups.com
The type of head changed in 0.15. It's explained in the announcement that head now returns a Maybe a so it can return a Nothing rather than crash on the empty list.

Because you know that the drop operation won't produce an empty list, try sticking |> Maybe.withDefault darkRed on the end. The default should never be used, so you can use whatever color you like. I chose darkRed so it's obvious something is wrong, just in case.

Bryan Muir

unread,
Apr 21, 2015, 1:31:23 PM4/21/15
to elm-d...@googlegroups.com
Thanks Max,

That worked of course, and after seeing it, it does make sense.  But that should didn't seem that obvious during the hour or so this morning I fought with it.

Maybe an FAQ/Recipe/Cookbook area should be set up where we can collect these rookie mistakes and show simple solutions like the one you gave me.  

Hassan Hayat

unread,
Apr 21, 2015, 1:54:48 PM4/21/15
to elm-d...@googlegroups.com
Maybe an FAQ/Recipe/Cookbook area should be set up where we can collect these rookie mistakes and show simple solutions like the one you gave me.  

That sounds like a good idea. Maybe a wiki page in the github repo of elm-lang/core would do the trick? Or perhaps a separate repo and all the wisdom goes in the issue tracker cuz that's the easiest place to share random stuff. After compiling loads of these bits of wisdom, it would be easy to then turn them into a book or a nice website that has chapters and stuff. 
Reply all
Reply to author
Forward
0 new messages