[elm-discuss] Decoder for Recursive Type

2017-03-11 Thread vishesh
Hi everyone,

I would like to write a customizable frontend where different roles in an 
organization see different widgets on their dashboard. The mapping for 
which widgets belong to which roles are stored in the server/database where 
they can be configured/enabled/disabled based on admin controls and the 
like.

To make the final dashboard, I will return some kind of template language 
that looks a lot like Elm's definition of Html with names of components 
that map to some components/view functions I've written in Elm:

type Template = Body String | Tag String (List (String, String)) (List 
Template)
makeHtml : Template -> Html Msg -- (i've written this function already)

Now, I'd like to write a decoder that can take Json Object that looks like 
the template object and converts it into the template object. 
Something like :

("tag", {"attr": "value"}, ["string body", ("tag2", {}, [])]) -> Tag "tag" 
[("attr", "value")] [Body "string body", Tag "tag2" [] []]

There are no tuples in Json, so instead I decided to go with an object:
{"tag" : "tag", "attrs" : {"attr" : "value"}, "body" : ["string body", 
{"tag" : "tag2", "attrs": {}, body: []}]}

Now I need to parse this object into the Template type.

In general, I'm interested in seeing what decoders look like for recursive 
types, like List, BinaryTree, RoseTree, and so on. What's the standard way 
to write them? I'm also not sure how to decode a union type like this one.



-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: Cmd Msg returned by init

2017-03-11 Thread Duane Johnson
Thank-you Ilias and Martin. Both approaches were novel and interesting to
me.

It turned out that in order to get data from the server, I had to create a
function with signature:

```
getStatus : Cmd Msg
getStatus =
Http.get (serverPrefix ++ "/api/status") decodeAll
|> RemoteData.sendRequest
|> Cmd.map GotStatus
```

So I was kind of going about it backwards. In the end, this is what my init
function looked like:

```
init : ( Model, Cmd Msg )
init =
( initialModel, getStatus )
```

The "leap" I was unable to make at first was that the same method that
`update` should call (on a timer) to trigger status updates from the server
is precisely the same function that `init` can call. So when I was trying
to call "RequestStatus", it was a synthetic (and unnecessary) message used
merely to get `update` to call `getStatus`:

```
-- Note: this is a simplified update function
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
RequestStatus time ->
( alertOnAnyFailure newModel, getStatus )
```

Just directly returning `getStatus` as the 2nd part of the tuple in the
`init` function is all that's necessary.

Duane

On Sat, Mar 11, 2017 at 8:39 AM, Ilias Van Peer  wrote:

> Let's take a step back, here.
>
> Conceptually, the `init` function is meant to say how to jumpstart your
> application. So what it should do, is provide the initial state of your
> model, and - optionally - telling the runtime to start executing some
> asynchronous task right away (a good example would be fetching some remote
> resource), as a Cmd.
>
> When the runtime receives such a Cmd, it will do what your commanded it to
> do, and then call your `update` function with the current state of the
> model and the Msg that resulted from your Cmd.
>
> Using `Task.perform` with a "no op" task to "trick" the runtime into
> calling your update feels wrong, as you say yourself. I'd argue that it's
> definitely abusing the the runtime, too.
>
> So, let's have a look at what you are trying to accomplish: you want to
> execute a function on your model, before declaring it "final". You could do
> that by calling `update` with the appropriate Msg from your init function,
> *or* you could split off that branch into a proper function that transforms
> your model.
>
> What you'd end up with, then, is something like this:
>
> ```
> init : (Model, Cmd msg)
> init =
>  ( initialModel |> transformIt, Cmd.none)
> ```
>
> Your update function would call that exact same function - which means you
> could think of the update function like a sort of "translation" from
> messages to function calls that transform your model, rather than the one
> central place to bundle all your logic.
>
> Hope this helps :)
>
> Kr,
>
> Ilias
>
> Op woensdag 8 maart 2017 22:50:00 UTC+1 schreef Duane Johnson:
>
>> Preface: while I've been using Elm for a while, I've only just begun
>> using messages and commands, so it's ok to treat me like a newbie here.
>> This is a capture of my experience of Elm while trying to figure out how to
>> send an initial message.
>>
>>
>> I find the `Cmd` type a little confusing, especially in the init
>> function. Conceptually, I want to "kick off" an initial fetch of data from
>> client to server, and it would make intuitive sense if I were permitted to
>> do this:
>>
>> ```
>> init : (Model, Msg)
>> init =
>> { initialModel, FetchStatus 0 }
>> ```
>>
>> But instead, the type of `init` is required to be this:
>>
>> ```
>> init : (Model, Cmd Msg)
>> init =
>> { initialModel, ... }
>> ```
>>
>> When I get to this point, I need to look up the documentation on Cmd.
>> Having read the guide several months ago, I have a vague impression that I
>> may need to "perform" something to get my message into a Cmd type. I look
>> at the `Platform.Cmd` documentation, and I see there's a `Cmd` type which
>> looks like a constructor. So I try this:
>>
>> ```
>> init : (Model, Cmd Msg)
>> init =
>> { initialModel, Cmd (FetchStatus 0) }
>> ```
>>
>> But I get an error: "Cannot find variable `Cmd`". Having some experience
>> with Elm, I believe this may mean although Cmd is a type, its constructor
>> is not exposed.
>>
>> At this point, the `map` function looks a little promising, because it
>> takes some things that are not Cmd and produces `Cmd msg`, i.e. precisely
>> the type I'm looking for. However, it's not clear to me what the first
>> parameter to map is (a function that takes `a` and produces `msg`?) There's
>> no documentation on this `map` function.
>>
>> Then I peruse the docs some more ("maybe this is so common a thing that
>> it belongs in Basics? or maybe I missed something in Platform, since Cmd is
>> a submodule of Platform?") and arrive at the Task documentation, where I
>> see the "perform" signature:
>>
>> perform
>>  :
>> (a -> msg) -> Task
>> 

[elm-discuss] Re: Cmd Msg returned by init

2017-03-11 Thread Ilias Van Peer
Let's take a step back, here.

Conceptually, the `init` function is meant to say how to jumpstart your 
application. So what it should do, is provide the initial state of your 
model, and - optionally - telling the runtime to start executing some 
asynchronous task right away (a good example would be fetching some remote 
resource), as a Cmd.

When the runtime receives such a Cmd, it will do what your commanded it to 
do, and then call your `update` function with the current state of the 
model and the Msg that resulted from your Cmd.

Using `Task.perform` with a "no op" task to "trick" the runtime into 
calling your update feels wrong, as you say yourself. I'd argue that it's 
definitely abusing the the runtime, too.

So, let's have a look at what you are trying to accomplish: you want to 
execute a function on your model, before declaring it "final". You could do 
that by calling `update` with the appropriate Msg from your init function, 
*or* you could split off that branch into a proper function that transforms 
your model.

What you'd end up with, then, is something like this:

```
init : (Model, Cmd msg)
init =
 ( initialModel |> transformIt, Cmd.none)
```

Your update function would call that exact same function - which means you 
could think of the update function like a sort of "translation" from 
messages to function calls that transform your model, rather than the one 
central place to bundle all your logic.

Hope this helps :)

Kr,

Ilias

Op woensdag 8 maart 2017 22:50:00 UTC+1 schreef Duane Johnson:
>
> Preface: while I've been using Elm for a while, I've only just begun using 
> messages and commands, so it's ok to treat me like a newbie here. This is a 
> capture of my experience of Elm while trying to figure out how to send an 
> initial message.
>
>
> I find the `Cmd` type a little confusing, especially in the init function. 
> Conceptually, I want to "kick off" an initial fetch of data from client to 
> server, and it would make intuitive sense if I were permitted to do this:
>
> ```
> init : (Model, Msg)
> init =
> { initialModel, FetchStatus 0 }
> ```
>
> But instead, the type of `init` is required to be this:
>
> ```
> init : (Model, Cmd Msg)
> init =
> { initialModel, ... }
> ```
>
> When I get to this point, I need to look up the documentation on Cmd. 
> Having read the guide several months ago, I have a vague impression that I 
> may need to "perform" something to get my message into a Cmd type. I look 
> at the `Platform.Cmd` documentation, and I see there's a `Cmd` type which 
> looks like a constructor. So I try this:
>
> ```
> init : (Model, Cmd Msg)
> init =
> { initialModel, Cmd (FetchStatus 0) }
> ```
>
> But I get an error: "Cannot find variable `Cmd`". Having some experience 
> with Elm, I believe this may mean although Cmd is a type, its constructor 
> is not exposed.
>
> At this point, the `map` function looks a little promising, because it 
> takes some things that are not Cmd and produces `Cmd msg`, i.e. precisely 
> the type I'm looking for. However, it's not clear to me what the first 
> parameter to map is (a function that takes `a` and produces `msg`?) There's 
> no documentation on this `map` function.
>
> Then I peruse the docs some more ("maybe this is so common a thing that it 
> belongs in Basics? or maybe I missed something in Platform, since Cmd is a 
> submodule of Platform?") and arrive at the Task documentation, where I see 
> the "perform" signature:
>
> perform 
>  : 
> (a -> msg) -> Task 
>  Never 
>  a 
> -> Cmd 
>  
> msg
>
> This looks promising as well, because it takes some things and produces a 
> `Cmd msg`. But the example in the documentation shows how to use `perform` 
> with `Time.now` which further confuses things because I just want to pass a 
> Time value to my FetchStatus, like it was meant to receive (not necessarily 
> a "now" value). If I try this:
>
> ```
> init : ( Model, Cmd Msg )
> init =
> ( initialModel, Task.perform FetchStatus 0 )
> ```
>
> I get
>
> ```
> Function `perform` is expecting the 2nd argument to be:
> Task.Task Never Time
> ```
>
> So finally I realize that I need to pass a "succeed" task to my `perform` 
> call so I can create a `Cmd msg` of the type I need:
>
> ```
> init : ( Model, Cmd Msg )
> init =
> ( initialModel, Task.perform FetchStatus (Task.succeed 0) )
> ```
>
> Subjectively, this all feels more convoluted than it needs to be. At a 
> basic level, I want to communicate an initial model and an initial "kick 
> off" message. It's confusing that Task types are involved in constructing 
> Cmd types. This makes finding the right documentation difficult. In 
> addition, it isn't clear why a Cmd is needed 

Re: [elm-discuss] Re: elm + reactive programming

2017-03-11 Thread Răzvan Cosmin Rădulescu
Interesting comparison, I need to check out this purescript some more. 
Never heard of it before but it does look like there are libraries that 
provide reactive functions or something, research time! Thanks :)

On Friday, March 10, 2017 at 8:14:59 PM UTC+1, jphedley wrote:
>
> Here's a nice balanced Pros & Cons Analysis of JavaScript vs Elm vs 
> PureScript vs GHCjs vs Scalajs 
>  
> Functional 
> UI Platforms, which includes Higher-Order Reflex FRP 
> .
>
>
> On Friday, March 10, 2017 at 10:21:43 AM UTC-8, Răzvan Cosmin Rădulescu 
> wrote:
>>
>> Well, I have to say, I didn't think the discussion will last this long to 
>> be honest, I'm pleasantly surprised :). From here on I'm going to handle it 
>> to you guys as you have more experience than I am have. I hope it gets 
>> somewhere constructive!
>>
>> On Friday, March 10, 2017 at 7:09:36 PM UTC+1, Peter Damoc wrote:
>>>
>>> On Fri, Mar 10, 2017 at 7:51 PM, Mark Hamburg  
>>> wrote:
>>>
 What it feels like one wants to write but can't is the function:

 throttle : Float -> Sub msg -> Sub msg

>>>
>>> I think you might be able to do this kind of thing in an Effects 
>>> Manager.  
>>>
>>>
>>>
>>> -- 
>>> There is NO FATE, we are the creators.
>>> blog: http://damoc.ro/
>>>
>>

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.


Re: [elm-discuss] Re: elm + reactive programming

2017-03-11 Thread Martin Norbäck Olivers
Yes, this is what I was talking about, we can abstract away the gritty 
details in functions even though we have the state explicitly in our model. 
I hadn't seen your package but it absolutely makes sense to do it this way.

Den fredag 10 mars 2017 kl. 19:33:03 UTC+1 skrev Matthieu Pizenberg:
>
>
> Let's consider throttling.
>> ...
>>
>  
> What you are describing here Mark is almost exactly what I implemented in 
> mpizenberg/elm-debounce [1]. I have no experience in observables and 
> unfortunately, do not know yet about effect managers so it is done with 
> messages. I agree that it has been painful, especially at the beginning. 
> But after many iterations, I think I got something working well and 
> relatively well designed (but that is not for me to judge).
>
> [1] http://package.elm-lang.org/packages/mpizenberg/elm-debounce/latest 
>

-- 
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+unsubscr...@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.