Well, it turns out the bug isn't in my code. It is in elm-lang/core
<https://github.com/elm-lang/core/issues/601>.

List.take fills ups the call stack all on its own:

main = [ 1 .. 5000 ] |> List.take 2500 |> toString |> Html.text

List.drop does not have this problem. If we redefine the partition function
solely in terms of List.drop, even the code in the OP works fine!

partition _ foos =
    let
        n = List.length foos // 2
    in
      ( List.reverse foos |> List.drop (n+1) |> List.reverse, List.drop n
foos )

I am happy that I learned how to use trampolines though. Maybe it will come
in handy some day :-)

On Tue, Jul 12, 2016 at 11:17 AM, Nick H <[email protected]> wrote:

> So I felt this 0.16 tutorial
> <https://www.classes.cs.uchicago.edu/archive/2015/winter/22300-1/lectures/TailRecursion.html>
> helped me understand trampolines better. Then it took a bit of work
> rewriting `create` in a way that utilized tail calls. But the new version
> is still failing with "too much recursion." Adding or removing the
> trampolines doesn't seem to make a difference.
>
> Below is a SSCCE, with dummy implementations for wrap and partition. In
> anybody has insight into what I am doing wrong, I would really appreciate
> it!
>
> module Main exposing (..)
>
> import Html
> import Dict exposing (Dict)
> import Trampoline exposing (Trampoline)
>
>
> main =
>     [1..4500] |> create |> toString |> Html.text
>
>
> create : List Foo -> Tree
> create foos =
>     Trampoline.evaluate (descend foos [])
>
>
> type Partial
>     = LeftBranch Bar (List Foo)
>     | RightBranch Bar Tree
>
>
> descend : List Foo -> List Partial -> Trampoline Tree
> descend incomplete stack =
>     case incomplete of
>         [] ->
>             Trampoline.jump (\_ -> ascend (Leaf emptyFoo) stack)
>
>         foo :: [] ->
>             Trampoline.jump (\_ -> ascend (Leaf foo) stack)
>
>         _ ->
>             Trampoline.jump
>                 (\_ ->
>                     let
>                         bar =
>                             wrap incomplete
>
>                         ( left, right ) =
>                             partition bar incomplete
>                     in
>                         descend left (LeftBranch bar right :: stack)
>                 )
>
>
> ascend : Tree -> List Partial -> Trampoline Tree
> ascend complete stack =
>     case stack of
>         [] ->
>             Trampoline.done complete
>
>         (LeftBranch parent sibling) :: remainder ->
>             Trampoline.jump
>                 (\_ ->
>                     descend sibling (RightBranch parent complete ::
> remainder)
>                 )
>
>         (RightBranch parent sibling) :: remainder ->
>             Trampoline.jump
>                 (\_ ->
>                     ascend (Node parent sibling complete) remainder
>                 )
>
>
> type alias Bar =
>     String
>
>
> type alias Foo =
>     Int
>
>
> type Tree
>     = Leaf Foo
>     | Node Bar Tree Tree
>
>
> wrap : List Foo -> Bar
> wrap =
>     toString
>
>
> partition : Bar -> List Foo -> ( List Foo, List Foo )
> partition _ foos =
>     let
>         n =
>             List.length foos // 2
>     in
>         ( List.take n foos, List.drop n foos )
>
>
> emptyFoo : Foo
> emptyFoo =
>     0
>
>
> On Tue, Jul 12, 2016 at 10:08 AM, Max Goldstein <[email protected]>
> wrote:
>
>> Nah, trampoline takes some mental gymnastics! Hope it's helpful for your
>> tree problem.
>>
>> --
>> 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 [email protected].
>> For more options, visit https://groups.google.com/d/optout.
>>
>
>

-- 
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 [email protected].
For more options, visit https://groups.google.com/d/optout.

Reply via email to