Okay, saw this only after sending my previous message. Still, the FilterOnly
message to be handled in update functions now is like a return of the
NothingHappened message that I was so happy to have eliminated. Plus, the
filters function’s added complexity. I still stand with “I’d rather have
the Keyboard API changed in the way I proposed, than to have to use this
more complicated machinery.”
​

2016-08-10 19:38 GMT+02:00 OvermindDL1 <[email protected]>:

> It would need the HandleKeyboardDown/Up messages, however I've recently
> made a change to my Msg structure so I have something like this:
> ```elm
>
> type alias MsgFiltered =
>   { HandleKeyboardUp Char
>   , HandleKeyboardDown Char
>   }
> type alias Msg
>   = FilterOnly MsgFiltered
>   | Other
>   | Interesting
>   | To
>   | Update
>   | Messages
>   | Like
>   | JumpDown
>   | JumpUp
>
> ```
> And it seems to be working well.  I just ignore the `FilterOnly` message
> entirely in my Update and can handle `FilterOnly` messages in the filter
> with ease (while still filtering others if I want).  It makes it easy to
> add messages that are only converted to others in the filter, then just
> subscribe to `(\c -> FilterOnly (TestFiltered c))` as normal.  That way you
> do not need to even have a case for them in your main update, just for the
> FilterOnly one, which you can just `( model, Cmd.none )` once.
>
>
> On Wednesday, August 10, 2016 at 11:22:47 AM UTC-6, Janis Voigtländer
> wrote:
>>
>> What will the GameMsg type look like?
>> ​
>>
>> 2016-08-10 18:59 GMT+02:00 OvermindDL1 <[email protected]>:
>>
>>> > If there are alternatives *with currently available functions* to my
>>> proposal, very interested to hear it in this thread.
>>>
>>> That is why I looked at more options and started thinking about how it
>>> could also solve other filtering issues that I have, so a singular thing
>>> that could solve it all would be nice.  :-)
>>>
>>>
>>> Given code from the dontfall game, the current top-post suggestion was
>>> to change subscriptions to be:
>>> ```elm
>>>
>>> subscriptions : GameData -> Sub GameMsgsubscriptions d =
>>>     Sub.batch
>>>         ([ Keyboard.downsSelectively (\c -> if Char.fromCode c == 'P' then 
>>> Just PauseToogle else Nothing) ] ++
>>>             if d.state == Running then
>>>                 [ AnimationFrame.diffs Tick
>>>                 , Keyboard.downsSelectively (\c -> if Char.fromCode c == ' 
>>> ' then Just JumpDown else Nothing)
>>>                 , Keyboard.upsSelectively (\c -> if Char.fromCode c == ' ' 
>>> then Just JumpUp else Nothing)
>>>                 ]
>>>             else
>>>                 [])
>>>
>>> ```
>>>
>>> In the thing I proposed that can handle generic message filtering (not
>>> just subscription) would turn the above back into a fairly normal and
>>> readable style of:
>>> ```elm
>>>
>>> subscriptions : GameData -> Sub GameMsgsubscriptions d =
>>>     Sub.batch
>>>       [ Keyboard.downs HandleKeyboardDown
>>>       , Keyboard.ups HandleKeyboardUps
>>>       , if d.state == Running then AnimationFrame.diffs Tick else Sub.none
>>>       ]
>>>
>>> ```
>>> And a new callback (added in the main where init/update/etc are, in my
>>> package is called 'filters') would be something like this, this is a very
>>> simple example and `filters` can do a lot more, but for simple keyboard
>>> filtering:
>>> ```elm
>>>
>>> filters : Msg -> Model -> ( Msg, States Model Msg )filters msg model =
>>>   if model.state == Running then
>>>     case msg of
>>>         HandleKeyboardDown c ->
>>>             case Char.fromCode c ->
>>>                 'P' -> ( PauseToggle, States.enableAll )
>>>                 ' ' -> ( JumpDown, States.enableAll )
>>>                 _ -> ( msg, States.disableAll )
>>>         HandleKeyboardUp c ->
>>>             case Char.fromCode c ->
>>>                 ' ' -> ( JumpUp, States.enableAll )
>>>                 _ -> ( msg, States.disableAll )
>>>         _ -> ( msg, States.enableAll )
>>>   else
>>>       ( msg, States.enableAll )
>>>
>>> ```
>>> You could also delegate to other TEA-style modules.  You could filter
>>> out the Tick here instead of subscribing and unsubscribing (I like a simple
>>> 'subscriptions' callback).  Anything with `States.disableAll` will disable
>>> all callbacks for that msg, so update will not be called, subscriptions
>>> will not be called, and view will not be called (it returns the cached
>>> values from last time so an exact match test of === in javascript shows
>>> they are identical and thus Elm will do nothing).
>>>
>>> With the above `filters` you will not ever get
>>> HandleKeyboardDown/HandleKeyboardUp in your `update` at all, ever, it
>>> is either translated to another message or entirely canceled.  Adding more
>>> message conversions is as simple as adding another case, so you could add,
>>> say a shooting state with like:
>>> ```elm
>>>
>>> filters : Msg -> Model -> ( Msg, States Model Msg )filters msg model =
>>>   if model.state == Running then
>>>     case msg of
>>>         HandleKeyboardDown c ->
>>>             case Char.fromCode c ->
>>>                 'P' -> ( PauseToggle, States.enableAll )
>>>                 ' ' -> ( JumpDown, States.enableAll )
>>>                 'z' -> ( StartShooting, States.enableAll )
>>>                 _ -> ( msg, States.disableAll )
>>>         HandleKeyboardUp c ->
>>>             case Char.fromCode c ->
>>>                 ' ' -> ( JumpUp, States.enableAll )
>>>                 'z' -> ( StopShooting, States.enableAll )
>>>                 _ -> ( msg, States.disableAll )
>>>         _ -> ( msg, States.enableAll )
>>>   else
>>>       ( msg, States.enableAll )
>>>
>>> ```
>>>
>>> Just as simple as adding a readable case to each the down and up to send
>>> the two StartShooting/StopShooting messages.  You could easily pull values
>>> from the model if the user can remap their keys and just do if's instead
>>> too.
>>>
>>> But yes, the filtering of messages is done in one and only area, and if
>>> you filter everything well then your update does not even need to become a
>>> mess of nested case's for the various states and such but you know that you
>>> will only get a message when it is actually valid for your state, so you
>>> know that you will not get a, say, `JumpUp` message unless you are in the
>>> `Running` state, so you do not even need to check that.  Your operations
>>> become simple and direct.
>>>
>>>
>>> On Wednesday, August 10, 2016 at 10:27:42 AM UTC-6, Janis Voigtländer
>>> wrote:
>>>>
>>>> Generally, Nick is right, I primarily want to hear feedback about the
>>>> specific API proposal I made.
>>>>
>>>> However, I wrote the other day that "If there are alternatives *with
>>>> currently available functions* to my proposal, very interested to hear
>>>> it in this thread."
>>>>
>>>> So since Overmind seems to since have released some package/functions
>>>> that are now available, it could be on-topic to see how/whether these do
>>>> address points I try to address with the API proposal. Hence my questions
>>>> (or "challenge" if you wish) in the previous message.
>>>>
>>>>
>>>> 2016-08-10 18:13 GMT+02:00 Nick H <[email protected]>:
>>>>
>>>>> That is not what this discussion is about. Janis proposed a change to
>>>>> the Keyboard API. The reason he started this thread was to get our 
>>>>> thoughts
>>>>> on his proposal.
>>>>>
>>>>> On Wed, Aug 10, 2016 at 8:37 AM, OvermindDL1 <[email protected]>
>>>>> wrote:
>>>>>
>>>>>> How is it off-topic considering its whole purpose is to handle this
>>>>>> exact kind of issue?  The discussion is about filtering messages,
>>>>>> potentially translating them to a a better message that is for a specific
>>>>>> purpose without needing to worry about checking for valid input in update
>>>>>> area.  It is handled generically.
>>>>>>
>>>>>>
>>>>>> On Wednesday, August 10, 2016 at 8:44:12 AM UTC-6, Nick H wrote:
>>>>>>>
>>>>>>> Overmind, we can all see the thread that you started. It is still
>>>>>>> off-topic for you to bring it up here.
>>>>>>>
>>>>>>> On Wed, Aug 10, 2016 at 7:40 AM, OvermindDL1 <[email protected]>
>>>>>>> wrote:
>>>>>>>
>>>>>>>> Well for what it is worth I made a library that can filter messages
>>>>>>>> before they are handled, so you could, for example, turn a keypress of 
>>>>>>>> 'w'
>>>>>>>> into a message of 'GoForward' and 's' into 'GoBackward' or whatever.  
>>>>>>>> And
>>>>>>>> if you cancel a message then it becomes entirely unhandled and you will
>>>>>>>> never even see it appear in the event loop (update/subscription/view). 
>>>>>>>>  If
>>>>>>>> your convert a message then you never see the original, only your 
>>>>>>>> converted
>>>>>>>> one.  I am curious if anyone wants to test it with these issues as I 
>>>>>>>> think
>>>>>>>> it would work very well as a, for example, key remapper.  It is a
>>>>>>>> nice-central place to put key mapping (since it has a model you could 
>>>>>>>> even
>>>>>>>> setup a dynamic key mapper based on user settings with ease).  Cleans 
>>>>>>>> up
>>>>>>>> code in update as since you can expect to only receive valid messages 
>>>>>>>> if
>>>>>>>> you filter them here first, vastly cleans up code there to only the 
>>>>>>>> actual
>>>>>>>> work.  The package is up at the elm package website (ProgramEx I think 
>>>>>>>> I
>>>>>>>> named it).  Still very in testing but it seems to be working utterly
>>>>>>>> perfect in one of my big apps and has already cleaned up a lot of code.
>>>>>>>> Here is how the filter code looks (this one 'delegates' to two 
>>>>>>>> different
>>>>>>>> TEA-form libraries their messages and alters a Scroll event just like 
>>>>>>>> you'd
>>>>>>>> expect to do with key remapping):
>>>>>>>>
>>>>>>>> ```elm
>>>>>>>>
>>>>>>>> filters : Msg -> Model -> ( Msg, States Model Msg )filters msg model =
>>>>>>>>     let
>>>>>>>>         log =
>>>>>>>>             debug_log (model.programFlags.debug_log |> 
>>>>>>>> Maybe.withDefault False) "filters" ( msg, model )
>>>>>>>>     in
>>>>>>>>         case msg of
>>>>>>>>             Helpers helpersMsg ->
>>>>>>>>                 ( msg
>>>>>>>>                 , States.enableAll |> States.delegate 
>>>>>>>> (helpers_delegate Helpers helpersMsg)
>>>>>>>>                 )
>>>>>>>>
>>>>>>>>             Mdl mdlMsg ->
>>>>>>>>                 ( msg
>>>>>>>>                 , States.enableAll
>>>>>>>>                     |> States.delegate
>>>>>>>>                         { key = "Mdl"
>>>>>>>>                         , update = Just (\_ o -> Material.update 
>>>>>>>> mdlMsg o)
>>>>>>>>                         , subscriptions = Just (\o -> 
>>>>>>>> Material.subscriptions Mdl o)
>>>>>>>>                         }
>>>>>>>>                 )
>>>>>>>>
>>>>>>>>
>>>>>>>>             MesgList_Scroll scrolled ->
>>>>>>>>                 case model.loc of
>>>>>>>>                     RoomLocation rid _ ->
>>>>>>>>                         let
>>>>>>>>                             doLoad : Bool
>>>>>>>>                             doLoad =
>>>>>>>>                                 (model.firstMessageReached == False)
>>>>>>>>                                     && (scrolled.pos < 16)
>>>>>>>>                                     && (model.isLoadingOlder == False)
>>>>>>>>
>>>>>>>>                                     && ((Dict.size 
>>>>>>>> model.active_room_msgs) >= 10)
>>>>>>>>
>>>>>>>>                         in
>>>>>>>>                             if doLoad then
>>>>>>>>                                 ( MesgList_LoadOlder rid, 
>>>>>>>> States.enableAll )
>>>>>>>>                             else
>>>>>>>>                                 ( msg, States.disableAll )
>>>>>>>>
>>>>>>>>                     _ ->
>>>>>>>>                         ( msg, States.disableAll )
>>>>>>>>
>>>>>>>>
>>>>>>>>             _ ->
>>>>>>>>                 ( msg, States.enableAll )
>>>>>>>>
>>>>>>>> ```
>>>>>>>>
>>>>>>>> On Tuesday, August 9, 2016 at 10:55:43 PM UTC-6, Nick H wrote:
>>>>>>>>>
>>>>>>>>> This would be a really nice improvement. I doubt there is anybody
>>>>>>>>> using the keyboard API who wants to capture every key press. (But 
>>>>>>>>> would
>>>>>>>>> love to see a counter-example!) Typing is handled by the HTML library
>>>>>>>>>
>>>>>>>>> On Mon, Aug 8, 2016 at 11:01 PM, Janis Voigtländer <
>>>>>>>>> [email protected]> wrote:
>>>>>>>>>
>>>>>>>>>> To up the proposal, here a revision.
>>>>>>>>>>
>>>>>>>>>> Instead of proposing to *add* new functions, I now propose to
>>>>>>>>>> *replace*
>>>>>>>>>>
>>>>>>>>>> Keyboard.presses : (KeyCode -> msg) -> Sub msgKeyboard.downs : 
>>>>>>>>>> (KeyCode -> msg) -> Sub msgKeyboard.ups : (KeyCode -> msg) -> Sub msg
>>>>>>>>>>
>>>>>>>>>> by
>>>>>>>>>>
>>>>>>>>>> Keyboard.presses : (KeyCode -> Maybe msg) -> Sub msgKeyboard.downs : 
>>>>>>>>>> (KeyCode -> Maybe msg) -> Sub msgKeyboard.ups : (KeyCode -> Maybe 
>>>>>>>>>> msg) -> Sub msg
>>>>>>>>>>
>>>>>>>>>> It would still be easy to recover the old behavior if wanted in a
>>>>>>>>>> specific situation, by throwing in Just. But actually I posit
>>>>>>>>>> that one almost never really wants to capture all keys. Usually, one 
>>>>>>>>>> wants
>>>>>>>>>> to be selective. That selectiveness has to be expressed somewhere, 
>>>>>>>>>> and
>>>>>>>>>> doing it with the Maybe type that is designed for such purpose
>>>>>>>>>> is generally better than going for something like extra NoOp or
>>>>>>>>>> NothingHappened or NotBound constructors that then need to be
>>>>>>>>>> handled in a special way in the app’s update logic, without help 
>>>>>>>>>> from the
>>>>>>>>>> type system. Making consideration of the selectiveness part of the
>>>>>>>>>> modelling up front would lead to better design. That’s at least the 
>>>>>>>>>> case in
>>>>>>>>>> the projects/repositories I have pointed to.
>>>>>>>>>> ​
>>>>>>>>>>
>>>>>>>>>> 2016-08-08 14:48 GMT+02:00 Janis Voigtländer <
>>>>>>>>>> [email protected]>:
>>>>>>>>>>
>>>>>>>>>>> A while back there was a thread
>>>>>>>>>>> <https://groups.google.com/d/msg/elm-discuss/u-6aCwaJezo/fu-HMPy6CQAJ>
>>>>>>>>>>> about filtering subscriptions. The following is related, but can 
>>>>>>>>>>> also (and
>>>>>>>>>>> probably better) be consumed and discussed independently. For those 
>>>>>>>>>>> that do
>>>>>>>>>>> have that older thread as context in mind, the following differs in 
>>>>>>>>>>> two
>>>>>>>>>>> essential ways:
>>>>>>>>>>>
>>>>>>>>>>>    - Earlier, the discussion was about generic filtering of
>>>>>>>>>>>    arbitrary subscriptions. The following involves no genericity 
>>>>>>>>>>> whatsoever.
>>>>>>>>>>>    It is only a proposal about the Keyboard API specifically.
>>>>>>>>>>>    - The earlier thread was not rooted in practice, since very
>>>>>>>>>>>    little stuff had been built yet with subscriptions. In the 
>>>>>>>>>>> following, I
>>>>>>>>>>>    point to how things have played out in practice, based on uses 
>>>>>>>>>>> students
>>>>>>>>>>>    have made of the current API in projects.
>>>>>>>>>>>
>>>>>>>>>>> ------------------------------
>>>>>>>>>>>
>>>>>>>>>>> So, on to the subject matter:
>>>>>>>>>>>
>>>>>>>>>>> The keyboard package
>>>>>>>>>>> <http://package.elm-lang.org/packages/elm-lang/keyboard>
>>>>>>>>>>> currently contains functions such as:
>>>>>>>>>>>
>>>>>>>>>>> Keyboard.downs : (KeyCode -> msg) -> Sub msg
>>>>>>>>>>>
>>>>>>>>>>> Common uses (I’ll point to several repositories below) are such
>>>>>>>>>>> that only some keys are relevant for an application. My proposal is 
>>>>>>>>>>> to have
>>>>>>>>>>> functions such as:
>>>>>>>>>>>
>>>>>>>>>>> Keyboard.downsSelectively : (KeyCode -> Maybe msg) -> Sub msg
>>>>>>>>>>>
>>>>>>>>>>> where the semantics is that if a given KeyCode is mapped to
>>>>>>>>>>> Nothing by the tagger, then no message gets sent along the
>>>>>>>>>>> subscription; otherwise the Just is peeled off and the message
>>>>>>>>>>> gets sent.
>>>>>>>>>>> ------------------------------
>>>>>>>>>>>
>>>>>>>>>>> Let’s look at a practical case, https://github.com/arpad-m/don
>>>>>>>>>>> tfall. It’s a game, where the player uses the keyboard for part
>>>>>>>>>>> of the control. Important excerpts from the code are:
>>>>>>>>>>>
>>>>>>>>>>> The message type (in https://github.com/arpad-m/don
>>>>>>>>>>> tfall/blob/master/src/BaseStuff.elm):
>>>>>>>>>>>
>>>>>>>>>>> type GameMsg = NothingHappened | ... several other messages ...
>>>>>>>>>>>
>>>>>>>>>>> The subscriptions definition (in https://github.com/arpad-m/don
>>>>>>>>>>> tfall/blob/master/src/main.elm):
>>>>>>>>>>>
>>>>>>>>>>> subscriptions : GameData -> Sub GameMsgsubscriptions d =
>>>>>>>>>>>     Sub.batch
>>>>>>>>>>>         ([ Keyboard.downs (\c -> if Char.fromCode c == 'P' then 
>>>>>>>>>>> PauseToogle else NothingHappened) ] ++
>>>>>>>>>>>             if d.state == Running then
>>>>>>>>>>>                 [ AnimationFrame.diffs Tick
>>>>>>>>>>>                 , Keyboard.downs (\c -> if Char.fromCode c == ' ' 
>>>>>>>>>>> then JumpDown else NothingHappened)
>>>>>>>>>>>                 , Keyboard.ups (\c -> if Char.fromCode c == ' ' 
>>>>>>>>>>> then JumpUp else NothingHappened)
>>>>>>>>>>>                 ]
>>>>>>>>>>>             else
>>>>>>>>>>>                 [])
>>>>>>>>>>>
>>>>>>>>>>> The main case distinction in the main update function (in
>>>>>>>>>>> https://github.com/arpad-m/dontfall/blob/master/src/main.elm):
>>>>>>>>>>>
>>>>>>>>>>> updateScene : GameMsg -> GameData -> (GameData, Cmd 
>>>>>>>>>>> GameMsg)updateScene msg d =
>>>>>>>>>>>     (case d.state of
>>>>>>>>>>>         ...
>>>>>>>>>>>         Running -> case msg of
>>>>>>>>>>>             MouseMove (x,_) -> { d | characterPosX = min x 
>>>>>>>>>>> d.flWidth}
>>>>>>>>>>>             Tick t -> stepTime d t
>>>>>>>>>>>             PauseToogle -> { d | state = Paused }
>>>>>>>>>>>             JumpDown -> { d | jumpPressed = True }
>>>>>>>>>>>             JumpUp -> { d | jumpPressed = False }
>>>>>>>>>>>             _ -> d
>>>>>>>>>>>     , Cmd.none
>>>>>>>>>>>     )
>>>>>>>>>>>
>>>>>>>>>>> Given availability of the functions I propose above, the code
>>>>>>>>>>> could instead look as follows:
>>>>>>>>>>>
>>>>>>>>>>> type GameMsg = ... only the other messages, no NothingHappened ...
>>>>>>>>>>> subscriptions : GameData -> Sub GameMsgsubscriptions d =
>>>>>>>>>>>     Sub.batch
>>>>>>>>>>>         ([ Keyboard.downsSelectively (\c -> if Char.fromCode c == 
>>>>>>>>>>> 'P' then Just PauseToogle else Nothing) ] ++
>>>>>>>>>>>             if d.state == Running then
>>>>>>>>>>>                 [ AnimationFrame.diffs Tick
>>>>>>>>>>>                 , Keyboard.downsSelectively (\c -> if Char.fromCode 
>>>>>>>>>>> c == ' ' then Just JumpDown else Nothing)
>>>>>>>>>>>                 , Keyboard.upsSelectively (\c -> if Char.fromCode c 
>>>>>>>>>>> == ' ' then Just JumpUp else Nothing)
>>>>>>>>>>>                 ]
>>>>>>>>>>>             else
>>>>>>>>>>>                 [])
>>>>>>>>>>> updateScene : GameMsg -> GameData -> (GameData, Cmd 
>>>>>>>>>>> GameMsg)updateScene msg d =
>>>>>>>>>>>     (case d.state of
>>>>>>>>>>>         ...
>>>>>>>>>>>         Running -> case msg of
>>>>>>>>>>>             MouseMove (x,_) -> { d | characterPosX = min x 
>>>>>>>>>>> d.flWidth}
>>>>>>>>>>>             Tick t -> stepTime d t
>>>>>>>>>>>             PauseToogle -> { d | state = Paused }
>>>>>>>>>>>             JumpDown -> { d | jumpPressed = True }
>>>>>>>>>>>             JumpUp -> { d | jumpPressed = False }
>>>>>>>>>>>     , Cmd.none
>>>>>>>>>>>     )
>>>>>>>>>>>
>>>>>>>>>>> Advantages:
>>>>>>>>>>>
>>>>>>>>>>>    1.
>>>>>>>>>>>
>>>>>>>>>>>    simpler message type, no special role no-op constructor
>>>>>>>>>>>    needed
>>>>>>>>>>>    2.
>>>>>>>>>>>
>>>>>>>>>>>    no spurious update and render cycles while the game is
>>>>>>>>>>>    running
>>>>>>>>>>>    3.
>>>>>>>>>>>
>>>>>>>>>>>    less room for bugs in the update logic
>>>>>>>>>>>
>>>>>>>>>>> Some additional comments on the latter two of these points:
>>>>>>>>>>>
>>>>>>>>>>> Re 2., given the current implementation, whenever a key is hit
>>>>>>>>>>> that is not relevant, the update function is still called and 
>>>>>>>>>>> produces an
>>>>>>>>>>> unchanged model, which is then rendered, which is extra/useless 
>>>>>>>>>>> work. Since
>>>>>>>>>>> the game uses Graphics.*, no use can be made of Html.Lazy.* to
>>>>>>>>>>> avoid the re-rendering. Even if something like Graphics.Lazy.*
>>>>>>>>>>> were available, having to use it would not be as nice/pure as not 
>>>>>>>>>>> causing
>>>>>>>>>>> those spurious updates in the first place.
>>>>>>>>>>>
>>>>>>>>>>> Re 3., given the current implementation, there is both more room
>>>>>>>>>>> for bugs in the now and in a potential later, when extending the 
>>>>>>>>>>> game. In
>>>>>>>>>>> the now, the programmer has to make sure that NothingHappened
>>>>>>>>>>> does indeed not change the model. Concerning later, imagine that the
>>>>>>>>>>> programmer extends the message type for some reason. With the 
>>>>>>>>>>> current
>>>>>>>>>>> version of updateScene, the programmer might forget to actually
>>>>>>>>>>> add a branch for handling the new message, and the compiler would 
>>>>>>>>>>> not catch
>>>>>>>>>>> that, because of the _ -> d branch that will silently catch not
>>>>>>>>>>> only NothingHappened but also the new message which was
>>>>>>>>>>> actually supposed to make something happen. With the version of
>>>>>>>>>>> updateScene after the proposed change, the situation would be
>>>>>>>>>>> different. Since there is no _ -> d branch in that Running ->
>>>>>>>>>>> case msg of ... part anymore (thanks to NothingHappened not
>>>>>>>>>>> being a thing), the compiler will immediately complain if the 
>>>>>>>>>>> message type
>>>>>>>>>>> is extended but the new message is not handled there. Bug prevented.
>>>>>>>>>>> ------------------------------
>>>>>>>>>>>
>>>>>>>>>>> It’s not only this single project. I have observed students
>>>>>>>>>>> applying different strategies to deal with “Not all keys are 
>>>>>>>>>>> relevant to my
>>>>>>>>>>> program”. In each case, using an API with functions of type (KeyCode
>>>>>>>>>>> -> Maybe msg) -> Sub msg instead of (KeyCode -> msg) -> Sub msg
>>>>>>>>>>> would have been conceptually nicer and would have simplified things.
>>>>>>>>>>>
>>>>>>>>>>> Some more example repos:
>>>>>>>>>>>
>>>>>>>>>>>    - https://github.com/chemmi/elm-rocket, uses type Key = Left
>>>>>>>>>>>    | Right | ... | NotBound and keyBinding : KeyCode -> Key and
>>>>>>>>>>>    then needs to make sure to correctly (non)-deal with NotBound
>>>>>>>>>>>    in functions like updateKeyDown; whereas just not having
>>>>>>>>>>>    NotBound, but having keyBinding : KeyCode -> Maybe Key and
>>>>>>>>>>>    using that in a call to a (KeyCode -> Maybe msg) -> Sub msg
>>>>>>>>>>>    function would simplify things with the same benefits as in the 
>>>>>>>>>>> above more
>>>>>>>>>>>    fully elaborated example case.
>>>>>>>>>>>    - https://github.com/Dinendal92/Abschlussprojekt-DP2016,
>>>>>>>>>>>    less complete project, but with same approach and issues as in 
>>>>>>>>>>> the
>>>>>>>>>>>    preceding example, using type Key = Space | Unknown and fromCode
>>>>>>>>>>>    : Int -> Key. Here, since eliminating Unknown would turn Key
>>>>>>>>>>>    into a type with only one constructor, even more conceptual 
>>>>>>>>>>> simplifications
>>>>>>>>>>>    would be enabled after a switch to the (KeyCode -> Maybe
>>>>>>>>>>>    msg) -> Sub msg approach.
>>>>>>>>>>>    - https://github.com/Shaomada/Elm-Project, quite elaborate
>>>>>>>>>>>    project, structured according to TEA, uses no special Key
>>>>>>>>>>>    type, instead maps with Char.fromCode in the calls to the
>>>>>>>>>>>    keyboard subscriptions, then has to case dispatch on actual
>>>>>>>>>>>    Chars at several places distributed over the update
>>>>>>>>>>>    functions of the TEA subcomponents. Subscribing with (KeyCode
>>>>>>>>>>>    -> Maybe msg) -> Sub msg functions should allow to eliminate
>>>>>>>>>>>    branches at some of those places, removing redundancies and room 
>>>>>>>>>>> for bugs.
>>>>>>>>>>>    - https://github.com/Sulring/elmaction, similar story
>>>>>>>>>>>    (without TEA)
>>>>>>>>>>>
>>>>>>>>>>> ​
>>>>>>>>>>>
>>>>>>>>>>
>>>>>>>>>> --
>>>>>>>>>> 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.
>>>>>>>>
>>>>>>>
>>>>>>> --
>>>>>> 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.
>>>>>
>>>>
>>>> --
>>> 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.
>

-- 
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