First three items of a list in Haskell -
i new haskell, , struggling bit function here. premise simple enough: run through list, , combine each 3 items next each other function , return list results. problem in nice way.
here i've got:
foo :: [int] -> [int] foo xs | length xs < 3 = [] | otherwise = n : foo (tail xs) n = calc (xs!!0) (xs!!1) (xs!!2) -- function more complicated. calc :: int -> int -> int -> int calc x y z = x + y - (z * 2) -- , can use this: foo [1,2,3] -- [-3] foo [1,2,3,4] -- [-3,-3] foo [1,1,5,3,3] -- [-8,0,2]
what don't like, 5th line, containing !!
's. feels i'm thinking wrong way, , there should better way of doing this. i'd like
foo (x:y:z:xs) -- ...
but fail when list gets less 3 items. so, i'd have declare other patterns when list has fewer items?
also, in case there function foo
(there is, seems there 1 everything), i'm not interested in it. i'm trying grok haskell way of doing things, more expanding repetoire of functions.
edit: in js, i'd n = calc.apply(null, take(3, xs))
. wonder if haskell has apply
takes array , applies function parameters.
edit 2 -- solution: (based on comment below)
foo (x:y:z:xs) = calc x y z : foo (y:z:xs) foo _ = []
last pattern match catch-all, if first "fails" fall through , return empty list.
well, foo (x:y:z:xs)
plus “too short clause” wouldn't bad solution. be
foo xs = case splitat 3 xs of ([x,y,z],xs') -> calc x y z : foo (y:z:xs') _ -> []
or, perhaps nicest,
import data.list (tails) foo xs = [ calc x y z | (x:y:z:_) <- tails xs ]
Comments
Post a Comment