haskell - generating the first n terms of the continued fraction expansion of a number -
edit: @downvoters: @ least please tell me how can improve question? tried best can, , getting downvotes without comment not constructive in opinion.
im still new haskell, , exercises, i'm trying make function, returns first n
terms of continued fraction expansion of x
. first argument x
can floting point or integral, second argument must int
. code far, load without error:
continuedfraction x n | x < 0 = [] | n < 1 = [] | otherwise = [floor x] ++ (take n (continuedfraction (1 / (x - floor x)) (n-1) ) )
(i aware not elegant, simplest 1 able come @ point.)
as use function e.g. continuedfraction 3.1415 4
error message below. can point out error / explain message?
(i did try make type definition ideas above, without success too: continuedfraction :: (num x) => x -> int -> [integer]
)
the error message (when running without type definition):
*main> continuedfraction 3.1415 4 <interactive>:86:1: not deduce (integral a0) arising use of `continuedfraction' context (integral t) bound inferred type of :: integral t => [t] @ <interactive>:86:1-26 type variable `a0' ambiguous note: there several potential instances: instance integral integer -- defined in `ghc.real' instance integral int -- defined in `ghc.real' instance integral word -- defined in `ghc.real' in expression: continuedfraction 3.1415 4 in equation `it': = continuedfraction 3.1415 4 <interactive>:86:19: not deduce (fractional a0) arising literal `3.1415' context (integral t) bound inferred type of :: integral t => [t] @ <interactive>:86:1-26 type variable `a0' ambiguous note: there several potential instances: instance integral => fractional (ghc.real.ratio a) -- defined in `ghc.real' instance fractional double -- defined in `ghc.float' instance fractional float -- defined in `ghc.float' in first argument of `continuedfraction', namely `3.1415' in expression: continuedfraction 3.1415 4 in equation `it': = continuedfraction 3.1415 4
advice
if beginner @ haskell there few rules should stick to:
- if have function, make sure give type signature expresses intended input/output
- if in doubt stick concrete types
double
on typeclassesfractional a
- if function working intended remove type signature or use language extension
-xscopedtypevariables
, ghci explore signatures compiler infer feel typeclasses
answer
now let explore function - want generate continued fraction assume formula have written down generating correct. haskell powerful enough model infinite lists let use power , rid of second parameter , generate (possibly) infinite list.
continuedfraction :: double -> [int]
so see - expecting double
input , result [int]
, i.e. list of integers, chose int
simplicity - huge integer
don't think algorithm neither stable nor efficient - , using double
's guess real problem floating point arithmetics.
continued fraction x | x < 0 = [] | otherwise = let = floor x x' = 1/(x - fromintegral i) in : continuedfraction x'
this simplest solution came with, problems had were
i :: int
,x :: double
in haskell cannot subtract things of different type, there no autoboxing/automatic coercion. control on things - compiler not smart enough infer 'obviously' wanted calculate (you see leads if use ms excel).the solution problem explicit conversion
fromintegral :: double -> int
in casefor readability switched
[a] ++
a :
equivalent, less write , more performant, performance not of concern here
using function in ghci: ghci myfile.hs
> continuedfraction 3.1415 [3,.....] --infinite list > take 4 $ continuedfraction 3.1415 [3,7,14,1]
now can explore function!
how use advice
{-# language scopedtypevariables#-} module so34830462 --continuedfraction :: double -> [int] continuedfraction :: double -> _ continuedfraction x | x < 0 = [] | otherwise = let = floor x x' = 1/ (x - fromintegral i) in : continuedfraction x'
ghci myfile.hs
leads error
ghci, version 7.10.2: http://www.haskell.org/ghc/ :? [1 of 1] compiling so34830462 ( 34830462.hs, interpreted ) myfile.hs:6:32: found hole ‘_’ type: [t] [...] continuedfraction :: integral t => double -> [t] [...] failed, modules loaded: none.
it tells in short - "oh didn't specify correct type signature", ghc use type signature.
you can substitute type signature , same double
parameter, exploring function bit bit.
if not sure start can omit type signature , call :t continuedfraction
iside ghci session.
Comments
Post a Comment