haskell - Is it square check -
i trying write function check if argument square of integer:
issquare :: int -> bool issquare x = truncate(sqrt(x)) * truncate(sqrt(x)) == x when loading function error:
prelude> :load "some.hs" [1 of 1] compiling main ( some.hs, interpreted ) some.hs:2:13: no instance (realfrac int) arising use of `truncate' @ some.hs:2:13-29 possible fix: add instance declaration (realfrac int) in first argument of `(*)', namely `truncate (sqrt (x))' in first argument of `(==)', namely `truncate (sqrt (x)) * truncate (sqrt (x))' in expression: truncate (sqrt (x)) * truncate (sqrt (x)) == x some.hs:2:22: no instance (floating int) arising use of `sqrt' @ some.hs:2:22-28 possible fix: add instance declaration (floating int) in first argument of `truncate', namely `(sqrt (x))' in first argument of `(*)', namely `truncate (sqrt (x))' in first argument of `(==)', namely `truncate (sqrt (x)) * truncate (sqrt (x))' failed, modules loaded: none. but if try execute:
prelude> truncate(sqrt(9))*truncate(sqrt(9))==9 true all fine.
why error , how fix ?
you're getting errors because of type mismatches. type of sqrt sqrt :: floating => -> a, , type of truncate truncate :: (realfrac a, integral b) => -> b. former says sqrt takes input floating-point number, , returns 1 of same type output; latter says can truncate real fractional number1 integral number. however, assert x int, , int isn't floating-point number. thus, second error: "no instance (floating int) arising use of `sqrt'". says because of sqrt x, wanted int floating-point number, there's no definition that. first error similar: since sqrt :: floating => -> a, output same input, you're trying call truncate on integer. of course makes no sense, since int not realfrac, , that's why first error. fixing easy:
issquare :: int -> bool issquare x = let x' = truncate $ sqrt (fromintegral x :: double) in x'*x' == x the fromintegral function has type fromintegral :: (integral a, num b) => -> b; can convert integral number any number @ all. why need tell haskell want produce double; it'd default anyway, it's nice clear (though not necessary). double instance both of floating , realfrac, can sqrt , truncate it. rearranged code little; way there how i'd write it, since way compute truncation , sqrt once. also, note if remove type signature, haskell infer more general type issquare :: integral => -> bool, since never assume x precisely int.
the reason truncate(sqrt(9))*truncate(sqrt(9))==9 returned true because of type of 9. can ask ghci tell this:
prelude> :t 9 9 :: (num t) => t in haskell, integral numeric literals have type num t => t (9.0, or number decimal point, has type fractional t => t). means can any kind of number @ all, thing. otherwise, 9 have int or integer, , defining new number types—or using both int , integer!2—would royal pain. thus, when write truncate(sqrt(9)), ghci determines 9 must instance of floating (from sqrt) , realfrac (from truncate), defaults double, making work. defaulting standard behavior numeric types (it's why leave out :: double in definition of issquare), though not else (except in ghci, extends convenience). since 9 isn't int, x is, don't need convert 9, need convert x.
1: difference between floating , realfrac that, instance, complex double instance of floating not realfrac, , rational instance of realfrac not floating. float , double instances of both.
2: in case haven't come across this, difference int finite-precision, , integer arbitrary-precision.
Comments
Post a Comment