Register a SA Forums Account here!
JOINING THE SA FORUMS WILL REMOVE THIS BIG AD, THE ANNOYING UNDERLINED ADS, AND STUPID INTERSTITIAL ADS!!!

You can: log in, read the tech support FAQ, or request your lost password. This dumb message (and those ads) will appear on every screen until you register! Get rid of this crap by registering your own SA Forums Account and joining roughly 150,000 Goons, for the one-time price of $9.95! We charge money because it costs us money per month for bills, and since we don't believe in showing ads to our users, we try to make the money back through forum registrations.
 
  • Locked thread
Sinestro
Oct 31, 2010

The perfect day needs the perfect set of wheels.

HappyHippo posted:

Agreed. I also think the whole "no monads!!!" thing itself is pretty silly. They've reimplemented Applicative like half a dozen times in the core libraries, its ridiculous that there's so many versions of map/map2/map3/... when they could just define them once and be done with it. Is this because typeclasses are difficult to implement, or is this from the "for your own good" school of language design? Or are they just concerned that people will be turned off the language if it has monads in it?

Type classes are fairly simple, really. It was very hard to implement the first time, but they're fairly understood. It's mostly the last two, with a heavy lean on the first part because type classes are "too complicated" for front end developers.

Edit: This video explains things well. Elm doesn't want to be a functional programming language for the browser, it wants to make front end development better while being as mainstream as possible. I don't think this will work, and it's stupid to try and just ignore important features because they're "scary".

Sinestro fucked around with this message at 02:49 on Dec 31, 2015

Adbot
ADBOT LOVES YOU

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
From what I see he's not ignoring it, but trying to get away without it for as long as possible to avoid bloating the language. Feels reasonable, and there's nothing saying it won't ever get implemented. I think it's a good thing that every feature will have to earn its spot, although I agree that typeclasses are kinda important. When I tried doing a typeclass style approach in Scala ( having played a lot with Haskell beforehand ) I realised just how much of a boon a good implementation of typeclasses is for cutting down on boilerplate. Unfortunately trying it in Scala, while possible, just feels nothing like it.

Asymmetrikon
Oct 30, 2009

I believe you're a big dork!
It's interesting that type classes would bloat the language, but record field addition/deletion was a-OK until they realized that it was useless.

Snak
Oct 10, 2005

I myself will carry you to the Gates of Valhalla...
You will ride eternal,
shiny and chrome.
Grimey Drawer
I got a B in my class, thanks for all the help everyone. I'm not sure I learned much from the class, because I got a 68 on the midterm, and a 69 on the final, but I got over 90% on all the assignment, and 100% and the extra credit on the last assignment.

There's lots of stuff I still don't understand though. What's a good resource for explaining the role of monads in language design? Like I get how they are used in Haskell, but in the hypothetical scenario where I was constructing a language, I wouldn't able to implement monads because I don't "get" them on a more basic level.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Considering in JavaScript land object literals get used as containers for absolutely everything, I think a good record syntax with extensibility and type checking makes a lot of sense, given the target audience and domain.

Doc Hawkins
Jun 15, 2010

Dashing? But I'm not even moving!


Snak posted:

There's lots of stuff I still don't understand though. What's a good resource for explaining the role of monads in language design? Like I get how they are used in Haskell, but in the hypothetical scenario where I was constructing a language, I wouldn't able to implement monads because I don't "get" them on a more basic level.

Check out Tom Stuart's material on them. Take your pick of videos, posts...there's even a Ruby gem on github, with an almost embarrassingly simple implementation.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



I'm OK if Elm doesn't have all the bells and whistles all the cool modern f-langs have because I'm just hoping to pick it up as a sane, clean way to make web front-ends and hopefully finally get my head around some functional syntax and concepts via a practical tool that might actually make stuff I want to do easier.

That presentation was great.

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Am I just super bad at this or am I finding the compiler bugs? Both?

code:
fold : (a -> b -> b) -> b -> Tree a -> b
fold func acc tree = 
    case tree of
      Empty -> acc
      Node value left right -> 
          --(func value (fold func acc left)) `func` (fold acc func right) -- crashes the compiler
        let 
          partial : Tree a -> b
          partial = (fold func acc)
        in
          (func value (partial left)) `func` (partial right)
code:
The left argument of `func` is causing a type mismatch.

101|           (func value (partial left)) `func` (partial right)
`func` is expecting the left argument to be a:

    a

But the left argument is:

    a

Hint: A type annotation is clashing with itself or with a sub-annotation. This
can be particularly tricky, so read more about it.
<[url]https://github.com/elm-lang/elm-compiler/blob/0.16.0/hints/type-annotations.md[/url]>
Uh, ok? :confused:

crazypenguin
Mar 9, 2005
nothing witty here, move along
I don't know Elm, but try removing the type signature on 'partial' and see if that works.

Lexically scoping type variables is a sort of newish thing, Elm may not support it? (That is, it's possible when you write 'Tree a' in 'partial' that the 'a' is a different 'a' from the one in the type of 'fold')

edit: It looks like i'm right. See the link they post in that very error message.

sarehu
Apr 20, 2007

(call/cc call/cc)
You're finding compiler bugs but your code won't typecheck anyway.

Your general traversal strategy isn't going to work. You only have func which is of type a -> b -> b. Thus there's no way you can combine the results of (partial left) and (partial right), because they both have type b. You'd need some sort of b -> b -> b function to do that.

sarehu fucked around with this message at 20:59 on Dec 31, 2015

VikingofRock
Aug 24, 2008




Munkeymon posted:

Am I just super bad at this or am I finding the compiler bugs? Both?

code:
fold : (a -> b -> b) -> b -> Tree a -> b
fold func acc tree = 
    case tree of
      Empty -> acc
      Node value left right -> 
          --(func value (fold func acc left)) `func` (fold acc func right) -- crashes the compiler
        let 
          partial : Tree a -> b
          partial = (fold func acc)
        in
          (func value (partial left)) `func` (partial right)
code:
The left argument of `func` is causing a type mismatch.

101|           (func value (partial left)) `func` (partial right)
`func` is expecting the left argument to be a:

    a

But the left argument is:

    a

Hint: A type annotation is clashing with itself or with a sub-annotation. This
can be particularly tricky, so read more about it.
<[url]https://github.com/elm-lang/elm-compiler/blob/0.16.0/hints/type-annotations.md[/url]>
Uh, ok? :confused:

Not sure what's up with that error message, but I think your problem is that in the last line, func value (partial left) is a b, and (partial right) is also a b, so you can't apply `func` to them.

Bognar
Aug 4, 2011

I am the queen of France
Hot Rope Guy
I don't think the compiler message is terribly helpful here (I feel like it should be saying the left argument is B, but I could be wrong). However, your fold isn't correct for a tree. You're calling (partial left) and (partial right) which uses the same accumulator (which is a problem) and returns a value of type B. You then try to feed two Bs into a function of type (A -> B -> B).

I think you want your final let..in clause to be something like:

code:
let
  leftFold = fold func acc left
  acc = func value leftFold
in
  fold func acc right
This folds the left sub-tree using acc, generates a new acc from the left-folded sub-tree and the current node's value, then passes that new acc down into the fold for the right sub-tree.

edit: beaten by a mile.

Bognar fucked around with this message at 21:13 on Dec 31, 2015

Munkeymon
Aug 14, 2003

Motherfucker's got an
armor-piercing crowbar! Rigoddamndicu𝜆ous.



Bognar posted:

I think you want your final let..in clause to be something like:

code:
let
  leftFold = fold func acc left
  acc = func value leftFold
in
  fold func acc right
This folds the left sub-tree using acc, generates a new acc from the left-folded sub-tree and the current node's value, then passes that new acc down into the fold for the right sub-tree.

Which I can rewrite to simply fold func (func value (fold func acc left)) right and now I feel like an idiot for not seeing that immediately, but I guess that means I'm making progress.

E: oh here's a shocker: it's way easier to look up type declarations in the docs than to try to infer them like I was doing ugh jfc

Munkeymon fucked around with this message at 22:39 on Dec 31, 2015

gonadic io
Feb 16, 2011

>>=
Doing lexically scoped type signatures like that is pretty useful (see the great video http://matthew.brecknell.net/post/hole-driven-haskell/) but, at least in Haskell, requires an extension ScopedTypeVariables and as far as I can tell from a cursory Google isn't supported in elm.

KaneTW
Dec 2, 2011

What GHC does is rename the type variables so things like that Elm error are obvious.
code:
module Error where

const' :: a -> b -> b
const' _ x = x'
  where
    x' :: b
    x' = x
code:
Error.hs:7:10: error:
    • Couldn't match expected type ‘b1’ with actual type ‘b’
      ‘b’ is a rigid type variable bound by
        the type signature for:
          const' :: forall a b. a -> b -> b
        at Error.hs:3:11
      ‘b1’ is a rigid type variable bound by
        the type signature for:
          x' :: forall b1. b1
        at Error.hs:6:11
    • In the expression: x
      In an equation for ‘x'’: x' = x
    • Relevant bindings include
        x' :: b1 (bound at Error.hs:7:5)
        x :: b (bound at Error.hs:4:10)
        const' :: a -> b -> b (bound at Error.hs:4:1)

9-Volt Assault
Jan 27, 2007

Beter twee tetten in de hand dan tien op de vlucht.
For people wanting to learn Haskell i can recommend the book Haskell Programming From First Principles. Its quite expensive ($60) and still in early access, but its up to ~1000 pages already. Its pretty much the only book thats up to date and explains Haskell from the basis. Its goal is to explain Haskell in such a way that you can learn and understand any Haskell library thats out there, instead of teaching you say web dev with a framework or whatever. A sample can be found here.

KaneTW
Dec 2, 2011

It's a good book. Certainly way better than the books I used when I learned Haskell.

Snak
Oct 10, 2005

I myself will carry you to the Gates of Valhalla...
You will ride eternal,
shiny and chrome.
Grimey Drawer

Charlie Mopps posted:

For people wanting to learn Haskell i can recommend the book Haskell Programming From First Principles. Its quite expensive ($60) and still in early access, but its up to ~1000 pages already. Its pretty much the only book thats up to date and explains Haskell from the basis. Its goal is to explain Haskell in such a way that you can learn and understand any Haskell library thats out there, instead of teaching you say web dev with a framework or whatever. A sample can be found here.

Oooh, I hope it stays that cheap until I get money. I only know C, Java, Python and some Haskell, but Haskell has pretty much become my favorite language. It makes so much sense to me.

VikingofRock
Aug 24, 2008




Charlie Mopps posted:

For people wanting to learn Haskell i can recommend the book Haskell Programming From First Principles. Its quite expensive ($60) and still in early access, but its up to ~1000 pages already. Its pretty much the only book thats up to date and explains Haskell from the basis. Its goal is to explain Haskell in such a way that you can learn and understand any Haskell library thats out there, instead of teaching you say web dev with a framework or whatever. A sample can be found here.

Added this to the OP. Thanks for the recommendation!

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

I didn't check this thread in a while and hey look a lot of Elm related posts. I feel like replying to some of them, so here goes.

Maluco Marinero posted:

So I'm going through a phase of being ridiculously sold on Elm and wanting to try something non trivial in it. Seriously watch Evan's Lets be Mainstream talk, it's amazing to see a young language in the front end with responsible management, ensuring you can actually rely on packages, coding style, etc etc.

The foundation of the elm architecture is great too. I had one question though that maybe fart simpson could help me with. With the StartApp package it has a way to send in inputs and map them to actions for the model. Do components have any way to request Signals themselves, as I can see cases where you'd have say a Draggable component, and that'd like to listen to the Mouse.position signal once you start dragging, or a timer listening to (Time.every Time.millisecond).

All that said though, the animation example nearly gets there with Effects.tick. You're element is always going to know whether it needs to be reading from a signal, with a Draggable it would have a state of Dragging so it knows to trigger an effect at that point, so I guess all I'd be looking for is a way to make a Signal be polled by a Task that you can map into an effect. Does this seem reasonable? If it's at all possible to collect from a Signal with a task then you can keep the Static Signals, yet only be turning them into actions when actually required, keeping the possible complications down of polling say the Mouse position continuously.

I guess what I'm looking for is just something that can do (Signal a -> Task Never a) and then if be golden. Elm could do with a Hoogle-like.

I'm not quite sure I understand your third paragraph, but in general for a subcomponent that needs an input signal like Mouse.position I'd just hook it up to the input section of StartApp.start and pass it down the chain to the component(s) that need it. There's likely some way this can be made a little more friendly, like how a more recent package named elm-transit seems to have made it easier to do things like time based animations in nested modules.

I'm not sure what complications you mean about polling the Mouse position. If you're using elm-html with the lazy functions then it shouldn't really be a performance hit, if that's what you mean.

Sinestro posted:

I'm curious about people's experiences using Elm to develop a traditional website versus a 'web app', in terms of stuff like URLs and just general advice.

So actually I've mostly used Elm for little apps and games, and not much for websites, but in the past few weeks I've been starting to make a website for a friend. It's been going well so far, and the most frustrating, hardest part of it is dealing with CSS. I hate CSS, but if what you're using Elm for is writing the HTML and replacing the JavaScript parts, then I find it pretty pleasant. What I'm doing now is here if you'd like to see what it looks like, or you can look around the source of the official Elm websites https://github.com/elm-lang/elm-lang.org and https://github.com/elm-lang/package.elm-lang.org.

The language itself seems really nice to me for this type of thing. The not so nice parts are basically the small community. Sometimes there's a thing you want to do, but there's no binding for it in the core libraries and nobody's made a package to do it yet, so you have to do it on your own. Sometimes it's surprisingly trivial stuff, like I wanted to know how far down the page someone has scrolled so far. I basically had to do it myself by writing a native binding library to turn window.pageYOffset into an input signal. My only other option here would have been to use a port and set up an event listener in my html file and pass in the values.

It's constantly getting better, but don't write stuff in Elm expecting mature frameworks or anything. It's still very much a young, experimental language. It's possible to get stuff done in it, and I really like working in it though, so if you do end up writing stuff in it you can actually help out the community by giving feedback or publishing new packages or something.

Rudest Buddhist posted:

I tried using elm on a little scheduling pet project and could not find a decent way to get around basic routing. I think it really shines on fancy single page web apps.

Maluco Marinero posted:

By the looks of it it's just missing a decent package. Routing in web apps is pretty straightforward if you know how to go about it, with something that can map paths to a Route Type with parameters.

You'd need to write Native bindings to do it properly in Elm though, so you can bind to the various page change events.

Routing is something people have talked about for a while, and only recently has there seemed to be any solution at all to it. I like the looks of elm-transit-router the best so far, and I'm going to try using it in my current project. The author just announced it on the mailing list like a week ago, though.

There have been bindings to the history API for a while, so I think everything necessary is already bound and packaged. If you feel like working with the URLs directly instead of using one of the only two existing routing packages, look here.

Maluco Marinero posted:

From what I see he's not ignoring it, but trying to get away without it for as long as possible to avoid bloating the language. Feels reasonable, and there's nothing saying it won't ever get implemented. I think it's a good thing that every feature will have to earn its spot, although I agree that typeclasses are kinda important. When I tried doing a typeclass style approach in Scala ( having played a lot with Haskell beforehand ) I realised just how much of a boon a good implementation of typeclasses is for cutting down on boilerplate. Unfortunately trying it in Scala, while possible, just feels nothing like it.

Yeah. Evan has a long term view of this stuff. He thinks it's harder to take language features away once people have started using them than it is to add new language features, and he really wants to keep the core language small and simple. He's not opposed to typeclasses, and I've seen him say several times on the mailing list that he knows he will eventually add typeclasses or something similar, but he doesn't seem to love typeclasses that much and wants to make sure there's not a better solution out there. There was an alternate version of the compiler that supported F# style computation expressions and I think it was done with records rather than typeclasses.

A year ago people didn't know how to trigger a state update from an action on a child component and there were some different proposals on what to do about it. People were talking about changing the Signal graph structure to allow looping signals in certain situations, some people wanted monadic signals, and eventually they went with what became Tasks and the Elm Architecture, which I think turned out pretty well. Also, Evan just left his previous company and got hired by another company that's been really active in the Elm community. They use Elm in their website and product quite a bit, and are probably the collectively most experienced group out there at actually using Elm to make real stuff, so we're expecting some positive changes in how development on the language goes. Specifically there's been a lot of talk about involving more people other than just Evan in development of the compiler and core libraries, and standardizing on a new system for native JS bindings that will allow people to do more stuff that just isn't easy right now.

I guess my point is Elm is still changing rapidly and the creator is finding it difficult to keep up as he's been The Only Guy up to this point. There's good ideas out there but a hesitance to make significant changes without really evaluating them first. I think these things will get better, but in the meantime if you want more of a haskell in the browser experience check out PureScript, which I haven't used but a lot of people seem to like.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

fart simpson posted:


I'm not quite sure I understand your third paragraph, but in general for a subcomponent that needs an input signal like Mouse.position I'd just hook it up to the input section of StartApp.start and pass it down the chain to the component(s) that need it. There's likely some way this can be made a little more friendly, like how a more recent package named elm-transit seems to have made it easier to do things like time based animations in nested modules.

I'm not sure what complications you mean about polling the Mouse position. If you're using elm-html with the lazy functions then it shouldn't really be a performance hit, if that's what you mean.

Im not concerned about the performance, more just good encapsulation. Generally when you mousedown on something Draggable you want to track the init position, and then poll mouse movements globally until mouseup. It'd be nice to encapsulate that as an effect that's just a task that gets the next notify call of a signal (and possibly combines signals if you needed to). That way the signals stay static, and the signal -> task can be mapped to actions specific to the component rather than being passed down from StartApp.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Maluco Marinero posted:

Im not concerned about the performance, more just good encapsulation. Generally when you mousedown on something Draggable you want to track the init position, and then poll mouse movements globally until mouseup. It'd be nice to encapsulate that as an effect that's just a task that gets the next notify call of a signal (and possibly combines signals if you needed to). That way the signals stay static, and the signal -> task can be mapped to actions specific to the component rather than being passed down from StartApp.

The real answer here is that this is type of thing is an ongoing discussion in the Elm community. There's people talking about wanting ore encapsulation like you describe, and there's other people talking about how they like how explicityly modeled everything is, and all that's really needed is something to reduce some of the boilerplate. I'm not sure what I think about all of it, but I kind of lean toward not thinking something like the Signal a -> Task Never a function would be a good thing. I find the more I work with the Elm Architecture and explicitly passing things down the hierarchy the more I appreciate how explicit everything is, and it makes stuff like more traditional components feel like a tricky implicitness. Like in your example, the Mouse position is an input that's needed to compute the full state of your program, isn't it?

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Elm really does need a Hoogle though. I kind of want to write one, but I'm not sure I'm up to it at the moment.

9-Volt Assault
Jan 27, 2007

Beter twee tetten in de hand dan tien op de vlucht.

Snak posted:

Oooh, I hope it stays that cheap until I get money. I only know C, Java, Python and some Haskell, but Haskell has pretty much become my favorite language. It makes so much sense to me.

It just got another update, up to 1156 pages now so even more direct value for your :10bux:

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.

fart simpson posted:

Elm really does need a Hoogle though. I kind of want to write one, but I'm not sure I'm up to it at the moment.

It's only okay if you do it in Elm, though.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

QuantumNinja posted:

It's only okay if you do it in Elm, though.

Well yeah. There's a parser combinator library I'd probably use.

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.

fart simpson posted:

The real answer here is that this is type of thing is an ongoing discussion in the Elm community. There's people talking about wanting ore encapsulation like you describe, and there's other people talking about how they like how explicityly modeled everything is, and all that's really needed is something to reduce some of the boilerplate. I'm not sure what I think about all of it, but I kind of lean toward not thinking something like the Signal a -> Task Never a function would be a good thing. I find the more I work with the Elm Architecture and explicitly passing things down the hierarchy the more I appreciate how explicit everything is, and it makes stuff like more traditional components feel like a tricky implicitness. Like in your example, the Mouse position is an input that's needed to compute the full state of your program, isn't it?

The problem with explicitly passing things down the hierarchy is that at a point you're preventing code reuse, because as per the architecture Actions are what get passed down, you could never write a nice module for Drag and Drop without boilerplate from outside to convert whatever the mouse input signal is to to the Drag and Drop's expected actions.

Maybe I just need to try another tack with this, but I just feel like it blocks off the kind of stuff I do with React components that can keep complex interaction code confined to the component in concern with a simple API that requires no internal knowledge.

QuantumNinja
Mar 8, 2013

Trust me.
I pretend to be a ninja.

Maluco Marinero posted:

The problem with explicitly passing things down the hierarchy is that at a point you're preventing code reuse, because as per the architecture Actions are what get passed down, you could never write a nice module for Drag and Drop without boilerplate from outside to convert whatever the mouse input signal is to to the Drag and Drop's expected actions.

Lenses could work.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Maluco Marinero posted:

The problem with explicitly passing things down the hierarchy is that at a point you're preventing code reuse, because as per the architecture Actions are what get passed down, you could never write a nice module for Drag and Drop without boilerplate from outside to convert whatever the mouse input signal is to to the Drag and Drop's expected actions.

Maybe I just need to try another tack with this, but I just feel like it blocks off the kind of stuff I do with React components that can keep complex interaction code confined to the component in concern with a simple API that requires no internal knowledge.

What's wrong with something like "Signal.map DragAction Mouse.position"?

This discussion on the mailing list seems relevant to what you're talking about, as is this one.. I tend to agree with what Richard Feldman is saying in both of these threads.

gonadic io
Feb 16, 2011

>>=

QuantumNinja posted:

Lenses could work.

Then you'd have 5(?) problems. Lenses have 5 type param these days right?

Fluue
Jan 2, 2008
I've been toying around with Elm lately and it's my first introduction to FP-style programming. I'm working on making a very basic Cookie Clicker clone to practice with Signals, but I'm hung up on how I should merge my model update (i.e. increment by 1) on both: a) every click (already have this handled as an onClick in a View element) and b) every 1 second that passes.

These actions are doing the same thing, so where would I add in a Signal handler to perform the "Increment" action every 1 second? Would it be a foldp or Signal.map that I'm thinking too hard about?

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Post some code? The answer is probably to Signal.map your input signals into an Increment action and merge them, then foldp the resulting action signal

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Also, why not use StartApp like everyone else these days? Are you trying to dig into Signals and FRP to understand it better?

Fluue
Jan 2, 2008

fart simpson posted:

Post some code? The answer is probably to Signal.map your input signals into an Increment action and merge them, then foldp the resulting action signal

Game model just defines clicks, level, and cps_multiplier.

code:
-- Update

type Action = Increment

doClick action game =
    case action of
        Increment -> { game | clicks = game.clicks + (1 * game.cps_multiplier) }

-- Where things get hazy for me: determining how to handle an every second Time update
tickerClick : Signal Action
tickerClick = Signal.map Increment (Time.every Time.second)

-- View

view : Signal.Address Action -> Game -> Html
view address game = 

    div []
        [ img [ src "assets/cookie.jpeg", onClick address Increment ] []
        , div [] [text (toString game.clicks)]
        ]

I am using StartApp but until now I've been using StartApp.simple which abstracts away some of the signal processing.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Try this, is it what you want? You basically just pass the mapped Increment action from the every second signal into the inputs field of the StartApp config
code:
type Action = Increment

ticker : Signal Action
ticker = Signal.map (always Increment) (Time.every Time.second)

type alias Game = { clicks : Int }

update : Action -> Game -> ( Game, Effects.Effects Action )
update action game =
    case action of
        Increment -> ( {game| clicks = game.clicks + 1 }, Effects.none )


view : Signal.Address Action -> Game -> Html
view address game = 
    div []
        [ img [ src "assets/cookie.jpeg", onClick address Increment ] []
        , div [] [text (toString game.clicks)]
        ]
        
app = 
    StartApp.start { init = (Game 0, Effects.none), update = update, view = view, inputs = [ticker] }
    
main = app.html

Fluue
Jan 2, 2008

fart simpson posted:

Try this, is it what you want? You basically just pass the mapped Increment action from the every second signal into the inputs field of the StartApp config

Perfect! I was about to post back with something similar (using input=[]). Is there a resource you have that explains why Effects.Effects needs to be used when dealing with this kind of signal? Is it because the ticker is constantly running?

Maluco Marinero
Jan 18, 2001

Damn that's a
fine elephant.
Effects is only necessary if you have Actions which kick off tasks (that then map to Actions)

Always on signals don't need that.

fart simpson
Jul 2, 2005

DEATH TO AMERICA
:xickos:

Fluue posted:

Perfect! I was about to post back with something similar (using input=[]). Is there a resource you have that explains why Effects.Effects needs to be used when dealing with this kind of signal? Is it because the ticker is constantly running?

Maluco Marinero is right, but StartApp.Simple doesn't have the inputs section that allows you to attach external Signals. The non-Simple StartApp has that, but it also requires you to specify Effects, even if those Effects are always none, like in my example.

ultrafilter
Aug 23, 2007

It's okay if you have any questions.


Speaking of functional languages for web development, there's a (very early) OCaml to Javascript compiler that might be interesting.

Adbot
ADBOT LOVES YOU

9-Volt Assault
Jan 27, 2007

Beter twee tetten in de hand dan tien op de vlucht.
The first Elm book will be coming:

https://twitter.com/rtfeldman/status/696710513342820352

  • Locked thread