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

Popular posts from this blog

asp.net - repeatedly call AddImageUrl(url) to assemble pdf document -

java - Android recognize cell phone with keyboard or not? -

iphone - How would you achieve a LED Scrolling effect? -