{"id":575,"date":"2022-08-30T15:03:38","date_gmt":"2022-08-30T15:03:38","guid":{"rendered":"https:\/\/unknownerror.org\/index.php\/2013\/11\/09\/haskell-operations-on-double-and-int-give-error-couldnt-match-expected-type-collection-of-common-programming-errors\/"},"modified":"2022-08-30T15:03:38","modified_gmt":"2022-08-30T15:03:38","slug":"haskell-operations-on-double-and-int-give-error-couldnt-match-expected-type-collection-of-common-programming-errors","status":"publish","type":"post","link":"https:\/\/unknownerror.org\/index.php\/2022\/08\/30\/haskell-operations-on-double-and-int-give-error-couldnt-match-expected-type-collection-of-common-programming-errors\/","title":{"rendered":"Haskell: Operations on Double and Int give error &ldquo;couldn&#39;t match expected type&rdquo;-Collection of common programming errors"},"content":{"rendered":"<p>I&#8217;m writing a interpreter for my own language and I have an abstract syntax tree which has this type:<\/p>\n<pre><code>data Expression = \n  PInt Int\n  | PFloat Double\n  | PString String\n  | PChar Char\n  | PBool Bool\n  | Var String\n  | Unbound String String\n  | Unary String Expression\n  | Binary String Expression Expression\n  | Call Expression [Expression]\n  | Lambda Expression\n  | Assign String Expression Expression\n  | Conditional Expression Expression Expression\n  deriving Eq\n<\/code><\/pre>\n<p>I&#8217;m trying to write an instance of Num for my class so that I can use existing machinery for numerical operations. Here&#8217;s what I&#8217;ve written:<\/p>\n<pre><code>instance Num Expression where\n   PInt a + PInt b = PInt $ a + b\n   PInt a + PFloat b = PFloat $ a + b\n   PFloat a + PInt b = PFloat $ a + b\n   PFloat a + PFloat b = PFloat $ a + b\n   _ + _ = undefined\n   PInt a - PInt b = PInt $ a - b\n   PInt a - PFloat b = PFloat $ a - b\n   PFloat a - PInt b = PFloat $ a - b\n   PFloat a - PFloat b = PFloat $ a - b\n   _ - _ = undefined\n   PInt a * PInt b = PInt $ a * b\n   PInt a * PFloat b = PFloat $ a * b\n   PFloat a * PInt b = PFloat $ a * b\n   PFloat a * PFloat b = PFloat $ a * b\n   _ * _ = undefined\n   negate (PInt a) = PInt (-a)\n   negate (PFloat a) = PFloat (-a)\n   negate _ = undefined\n   abs (PInt a) = PInt $ abs a\n   abs (PFloat a) = PFloat $ abs a\n   abs _ = undefined\n   signum (PInt a) = PInt $ signum a\n   signum (PFloat a) = PFloat $ signum a\n   signum _ = undefined\n   fromInteger i = (PInt $ fromInteger i)\n<\/code><\/pre>\n<p>This gives me errors specifically in the places where I&#8217;ve combined ints and floats.<\/p>\n<pre><code>Prelude&gt; :load AST.hs\n[1 of 1] Compiling AST          ( AST.hs, interpreted )\n\nAST.hs:38:36:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the first argument of `(+)', namely `a'\n    In the first argument of `PFloat', namely `(a + b)'\n    In the expression: PFloat (a + b)\n\nAST.hs:39:37:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the second argument of `(+)', namely `b'\n    In the second argument of `($)', namely `a + b'\n    In the expression: PFloat $ a + b\n\nAST.hs:43:33:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the first argument of `(-)', namely `a'\n    In the second argument of `($)', namely `a - b'\n    In the expression: PFloat $ a - b\n\nAST.hs:44:37:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the second argument of `(-)', namely `b'\n    In the second argument of `($)', namely `a - b'\n    In the expression: PFloat $ a - b\n\nAST.hs:48:33:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the first argument of `(*)', namely `a'\n    In the second argument of `($)', namely `a * b'\n    In the expression: PFloat $ a * b\n\nAST.hs:49:37:\n    Couldn't match expected type `Double' with actual type `Int'\n    In the second argument of `(*)', namely `b'\n    In the second argument of `($)', namely `a * b'\n    In the expression: PFloat $ a * b\nFailed, modules loaded: none.\n<\/code><\/pre>\n<p>This doesn&#8217;t make sense to me, since the type of an Int + Double in Haskell is a Double, so a + b should resolve to a Double, and since the constructor for a PFloat takes a Double, no problem&#8230; why is this not the case?<\/p>\n<p>Resolved: using <code>fromIntegral<\/code> in front of the variables of type <code>Int<\/code> fixes it.<\/p>\n<ol>\n<li>\n<p>The mathematical operators in the Num typeclass expect both of their arguments to have the same type, so you&#8217;ll have to convert the Int to a Double using <code>fromIntegral<\/code> before you can add them together.<\/p>\n<p>For example, replace this<\/p>\n<pre><code>PInt a + PFloat b = PFloat $ a + b\n<\/code><\/pre>\n<p>with this<\/p>\n<pre><code>PInt a + PFloat b = PFloat $ fromIntegral a + b\n<\/code><\/pre>\n<\/li>\n<\/ol>\n<p id=\"rop\"><small>Originally posted 2013-11-09 21:02:54. <\/small><\/p>","protected":false},"excerpt":{"rendered":"<p>I&#8217;m writing a interpreter for my own language and I have an abstract syntax tree which has this type: data Expression = PInt Int | PFloat Double | PString String | PChar Char | PBool Bool | Var String | Unbound String String | Unary String Expression | Binary String Expression Expression | Call Expression [&hellip;]<\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[1],"tags":[],"class_list":["post-575","post","type-post","status-publish","format-standard","hentry","category-uncategorized"],"_links":{"self":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/575","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/comments?post=575"}],"version-history":[{"count":0,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/posts\/575\/revisions"}],"wp:attachment":[{"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/media?parent=575"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/categories?post=575"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/unknownerror.org\/index.php\/wp-json\/wp\/v2\/tags?post=575"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}