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] <javascript:>>:
>
>> > 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/dontfall. 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/dontfall/blob/master/src/BaseStuff.elm
>>>>>>>>>> ):
>>>>>>>>>>
>>>>>>>>>> type GameMsg = NothingHappened | ... several other messages ...
>>>>>>>>>>
>>>>>>>>>> The subscriptions definition (in 
>>>>>>>>>> https://github.com/arpad-m/dontfall/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] <javascript:>.
>> 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