Composite Types and Html onInput












3















A week ago I finally found a way to split up my messages in different categories (Here is the SO question where I got my answer)



Now I have implemented this solution:



type Msg 
= AMsg AMsg
| BMsg BMsg
| CMsg CMsg


and then I defined AMsg as follows



type AMsg
= ActionOne Int String
| ActionTwo Int


Everything works great except when I use ActionOne with a onInput Html.Event



input [onInput (AMsg (ActionOne model.id))] 


This errors out telling me that onInput needs a String -> Msg type but is getting a AMsg type.



This would work just fine if I was using onClick for example and pass in the second argument myself



input [onClick (AMsg (ActionOne model.id "hello"))] 


But since I need to use onInput and that is what passes the second String parameter to ActionOne I am stuck. If I change my types to adapt to this



type Msg 
= AMsg AMsg String
| BMsg BMsg
| CMsg CMsg

type AMsg
= ActionOne Int
| ActionTwo Int


This works, but then i force ActionTwo to also take a string, which i don't want.



Otherwise I am stuck specifying ActionOne directly under Msg



type Msg 
= AMsg AMsg
| BMsg BMsg
| CMsg CMsg
| ActionOne Int String

type AMsg
= ActionTwo Int


I really care about separating Msgs into different categories -- if I want to use elm for a bigger project this seems pretty crucial to me. Any ideas ?










share|improve this question



























    3















    A week ago I finally found a way to split up my messages in different categories (Here is the SO question where I got my answer)



    Now I have implemented this solution:



    type Msg 
    = AMsg AMsg
    | BMsg BMsg
    | CMsg CMsg


    and then I defined AMsg as follows



    type AMsg
    = ActionOne Int String
    | ActionTwo Int


    Everything works great except when I use ActionOne with a onInput Html.Event



    input [onInput (AMsg (ActionOne model.id))] 


    This errors out telling me that onInput needs a String -> Msg type but is getting a AMsg type.



    This would work just fine if I was using onClick for example and pass in the second argument myself



    input [onClick (AMsg (ActionOne model.id "hello"))] 


    But since I need to use onInput and that is what passes the second String parameter to ActionOne I am stuck. If I change my types to adapt to this



    type Msg 
    = AMsg AMsg String
    | BMsg BMsg
    | CMsg CMsg

    type AMsg
    = ActionOne Int
    | ActionTwo Int


    This works, but then i force ActionTwo to also take a string, which i don't want.



    Otherwise I am stuck specifying ActionOne directly under Msg



    type Msg 
    = AMsg AMsg
    | BMsg BMsg
    | CMsg CMsg
    | ActionOne Int String

    type AMsg
    = ActionTwo Int


    I really care about separating Msgs into different categories -- if I want to use elm for a bigger project this seems pretty crucial to me. Any ideas ?










    share|improve this question

























      3












      3








      3








      A week ago I finally found a way to split up my messages in different categories (Here is the SO question where I got my answer)



      Now I have implemented this solution:



      type Msg 
      = AMsg AMsg
      | BMsg BMsg
      | CMsg CMsg


      and then I defined AMsg as follows



      type AMsg
      = ActionOne Int String
      | ActionTwo Int


      Everything works great except when I use ActionOne with a onInput Html.Event



      input [onInput (AMsg (ActionOne model.id))] 


      This errors out telling me that onInput needs a String -> Msg type but is getting a AMsg type.



      This would work just fine if I was using onClick for example and pass in the second argument myself



      input [onClick (AMsg (ActionOne model.id "hello"))] 


      But since I need to use onInput and that is what passes the second String parameter to ActionOne I am stuck. If I change my types to adapt to this



      type Msg 
      = AMsg AMsg String
      | BMsg BMsg
      | CMsg CMsg

      type AMsg
      = ActionOne Int
      | ActionTwo Int


      This works, but then i force ActionTwo to also take a string, which i don't want.



      Otherwise I am stuck specifying ActionOne directly under Msg



      type Msg 
      = AMsg AMsg
      | BMsg BMsg
      | CMsg CMsg
      | ActionOne Int String

      type AMsg
      = ActionTwo Int


      I really care about separating Msgs into different categories -- if I want to use elm for a bigger project this seems pretty crucial to me. Any ideas ?










      share|improve this question














      A week ago I finally found a way to split up my messages in different categories (Here is the SO question where I got my answer)



      Now I have implemented this solution:



      type Msg 
      = AMsg AMsg
      | BMsg BMsg
      | CMsg CMsg


      and then I defined AMsg as follows



      type AMsg
      = ActionOne Int String
      | ActionTwo Int


      Everything works great except when I use ActionOne with a onInput Html.Event



      input [onInput (AMsg (ActionOne model.id))] 


      This errors out telling me that onInput needs a String -> Msg type but is getting a AMsg type.



      This would work just fine if I was using onClick for example and pass in the second argument myself



      input [onClick (AMsg (ActionOne model.id "hello"))] 


      But since I need to use onInput and that is what passes the second String parameter to ActionOne I am stuck. If I change my types to adapt to this



      type Msg 
      = AMsg AMsg String
      | BMsg BMsg
      | CMsg CMsg

      type AMsg
      = ActionOne Int
      | ActionTwo Int


      This works, but then i force ActionTwo to also take a string, which i don't want.



      Otherwise I am stuck specifying ActionOne directly under Msg



      type Msg 
      = AMsg AMsg
      | BMsg BMsg
      | CMsg CMsg
      | ActionOne Int String

      type AMsg
      = ActionTwo Int


      I really care about separating Msgs into different categories -- if I want to use elm for a bigger project this seems pretty crucial to me. Any ideas ?







      elm






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked Nov 22 '18 at 2:12









      Nicola PedrettiNicola Pedretti

      1,89911723




      1,89911723
























          2 Answers
          2






          active

          oldest

          votes


















          4














          The function that you pass to onInput has to have the type String -> msg (or more specifically in your case, String -> Msg.)



          You can accomplish that by using a lambda:



          input [onInput (str -> (AMsg (ActionOne model.id str)))] 


          You can also use function composition (the << function) to achieve the same thing without needing to talk about the parameter str explicitly:



          input [ onInput <| AMsg << ActionOne model.id ]





          share|improve this answer































            1














            To expand a bit on answer of Matt McHenry:



            Sometimes when you have more complicated cases, it helps to think more closely what the usual simpler syntax actually means. When you have the basic case of



            type Msg
            = GotInput String
            ...
            input [onInput GotInput]


            then GotInput here is a function String -> Msg. You can also write this out explicitly as:



            input [onInput (str -> GotInput str)] 


            So here you give onInput a function which takes str parameter and then returns GotInput str.



            Now that you have this basic function, it can become clearer how to extend this to more complex case - you just change return value and include str at correct place in it:



            input [onInput (str -> (AMsg (ActionOne model.id str)))] 





            share|improve this answer























              Your Answer






              StackExchange.ifUsing("editor", function () {
              StackExchange.using("externalEditor", function () {
              StackExchange.using("snippets", function () {
              StackExchange.snippets.init();
              });
              });
              }, "code-snippets");

              StackExchange.ready(function() {
              var channelOptions = {
              tags: "".split(" "),
              id: "1"
              };
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function() {
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled) {
              StackExchange.using("snippets", function() {
              createEditor();
              });
              }
              else {
              createEditor();
              }
              });

              function createEditor() {
              StackExchange.prepareEditor({
              heartbeatType: 'answer',
              autoActivateHeartbeat: false,
              convertImagesToLinks: true,
              noModals: true,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: 10,
              bindNavPrevention: true,
              postfix: "",
              imageUploader: {
              brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
              contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
              allowUrls: true
              },
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              });


              }
              });














              draft saved

              draft discarded


















              StackExchange.ready(
              function () {
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53422973%2fcomposite-types-and-html-oninput%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              4














              The function that you pass to onInput has to have the type String -> msg (or more specifically in your case, String -> Msg.)



              You can accomplish that by using a lambda:



              input [onInput (str -> (AMsg (ActionOne model.id str)))] 


              You can also use function composition (the << function) to achieve the same thing without needing to talk about the parameter str explicitly:



              input [ onInput <| AMsg << ActionOne model.id ]





              share|improve this answer




























                4














                The function that you pass to onInput has to have the type String -> msg (or more specifically in your case, String -> Msg.)



                You can accomplish that by using a lambda:



                input [onInput (str -> (AMsg (ActionOne model.id str)))] 


                You can also use function composition (the << function) to achieve the same thing without needing to talk about the parameter str explicitly:



                input [ onInput <| AMsg << ActionOne model.id ]





                share|improve this answer


























                  4












                  4








                  4







                  The function that you pass to onInput has to have the type String -> msg (or more specifically in your case, String -> Msg.)



                  You can accomplish that by using a lambda:



                  input [onInput (str -> (AMsg (ActionOne model.id str)))] 


                  You can also use function composition (the << function) to achieve the same thing without needing to talk about the parameter str explicitly:



                  input [ onInput <| AMsg << ActionOne model.id ]





                  share|improve this answer













                  The function that you pass to onInput has to have the type String -> msg (or more specifically in your case, String -> Msg.)



                  You can accomplish that by using a lambda:



                  input [onInput (str -> (AMsg (ActionOne model.id str)))] 


                  You can also use function composition (the << function) to achieve the same thing without needing to talk about the parameter str explicitly:



                  input [ onInput <| AMsg << ActionOne model.id ]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 22 '18 at 4:16









                  Matt McHenryMatt McHenry

                  14.3k65459




                  14.3k65459

























                      1














                      To expand a bit on answer of Matt McHenry:



                      Sometimes when you have more complicated cases, it helps to think more closely what the usual simpler syntax actually means. When you have the basic case of



                      type Msg
                      = GotInput String
                      ...
                      input [onInput GotInput]


                      then GotInput here is a function String -> Msg. You can also write this out explicitly as:



                      input [onInput (str -> GotInput str)] 


                      So here you give onInput a function which takes str parameter and then returns GotInput str.



                      Now that you have this basic function, it can become clearer how to extend this to more complex case - you just change return value and include str at correct place in it:



                      input [onInput (str -> (AMsg (ActionOne model.id str)))] 





                      share|improve this answer




























                        1














                        To expand a bit on answer of Matt McHenry:



                        Sometimes when you have more complicated cases, it helps to think more closely what the usual simpler syntax actually means. When you have the basic case of



                        type Msg
                        = GotInput String
                        ...
                        input [onInput GotInput]


                        then GotInput here is a function String -> Msg. You can also write this out explicitly as:



                        input [onInput (str -> GotInput str)] 


                        So here you give onInput a function which takes str parameter and then returns GotInput str.



                        Now that you have this basic function, it can become clearer how to extend this to more complex case - you just change return value and include str at correct place in it:



                        input [onInput (str -> (AMsg (ActionOne model.id str)))] 





                        share|improve this answer


























                          1












                          1








                          1







                          To expand a bit on answer of Matt McHenry:



                          Sometimes when you have more complicated cases, it helps to think more closely what the usual simpler syntax actually means. When you have the basic case of



                          type Msg
                          = GotInput String
                          ...
                          input [onInput GotInput]


                          then GotInput here is a function String -> Msg. You can also write this out explicitly as:



                          input [onInput (str -> GotInput str)] 


                          So here you give onInput a function which takes str parameter and then returns GotInput str.



                          Now that you have this basic function, it can become clearer how to extend this to more complex case - you just change return value and include str at correct place in it:



                          input [onInput (str -> (AMsg (ActionOne model.id str)))] 





                          share|improve this answer













                          To expand a bit on answer of Matt McHenry:



                          Sometimes when you have more complicated cases, it helps to think more closely what the usual simpler syntax actually means. When you have the basic case of



                          type Msg
                          = GotInput String
                          ...
                          input [onInput GotInput]


                          then GotInput here is a function String -> Msg. You can also write this out explicitly as:



                          input [onInput (str -> GotInput str)] 


                          So here you give onInput a function which takes str parameter and then returns GotInput str.



                          Now that you have this basic function, it can become clearer how to extend this to more complex case - you just change return value and include str at correct place in it:



                          input [onInput (str -> (AMsg (ActionOne model.id str)))] 






                          share|improve this answer












                          share|improve this answer



                          share|improve this answer










                          answered Nov 22 '18 at 13:09









                          Markus LaireMarkus Laire

                          1,8471120




                          1,8471120






























                              draft saved

                              draft discarded




















































                              Thanks for contributing an answer to Stack Overflow!


                              • Please be sure to answer the question. Provide details and share your research!

                              But avoid



                              • Asking for help, clarification, or responding to other answers.

                              • Making statements based on opinion; back them up with references or personal experience.


                              To learn more, see our tips on writing great answers.




                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function () {
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f53422973%2fcomposite-types-and-html-oninput%23new-answer', 'question_page');
                              }
                              );

                              Post as a guest















                              Required, but never shown





















































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown

































                              Required, but never shown














                              Required, but never shown












                              Required, but never shown







                              Required, but never shown







                              Popular posts from this blog

                              Costa Masnaga

                              Fotorealismo

                              Sidney Franklin