From: Dave Burt Date: 2005-10-20T14:46:58+09:00 Subject: Re: Functional with Ruby Andreas Semt: > listSum [] = 0 > listSum (x : xs) = x + listSum xs Ara.T.Howard: > list_sum = lambda{|*list| list.flatten!; list.empty? ? 0 : list.shift + > list_sum[list] } Dave Burt: > list_sum = Proc.new {|x, *xs| if x then x + list_sum[*xs] else 0 end } Ara.T.Howard: > def self.list_sum x = nil, *xs > x ? x + list_sum(*xs) : 0 > end > list_sum = method 'list_sum' Quite. Module#method is one of Ruby's most underrated methods. [OT] How are you finding OCaml? I'm enjoying my trek into Haskell. And now for something completely different: a chunk of the Haskell Standard Prelude written directly in Ruby. I seem to have left the Haskell type definitions there, too. Cheers, Dave # plus :: Num -> Num -> Num plus = proc {|x| proc {|y| x + y } } # curry :: ((a, b) -> c) -> a -> b -> c curry = proc {|f| proc {|x| proc {|y| f[x, y] } } } # uncurry :: (a -> b -> c) -> (a, b) -> c uncurry = proc {|f| proc {|x, y| f[x][y] } } # flip :: (a -> b -> c) -> b -> a -> c flip = proc {|f| proc {|x| proc {|y| f[y][x] } } } # seq :: a -> b -> b #? # error :: String -> a error = proc {|s| raise s } # not :: Bool -> Bool _not = proc {|b| not b } # fst :: (a, b) -> a fst = proc {|x, y| x } # snd :: (a, b) -> b snd = proc {|x, y| y } # (:) :: a -> [a] -> [a] cons = proc {|head| proc {|list| [head] + list } } # (.) :: (b -> c) -> (a -> b) -> a -> c funcComp = proc {|f| proc {|g| proc {|x| f[g[x]] } } } # PreludeList #map :: (a -> b) -> [a] -> [b] map = proc {|f| proc {|x| if x==[] then [] else cons[f[head[x]]][map[f][tail[x]]] end }} # (++) :: [a] -> [a] -> [a] listJoin = proc {|x| proc {|y| if x==[] then y else cons[head[x]][listJoin[tail[x]][y]] end }} # filter :: (a -> Bool) -> [a] -> [a] filter = proc {|p| proc {|x| if x==[] [] elsif p[x] cons[head[x]][filter[p][tail[x]]] else filter[p][tail[x]] end }} # concat :: [[a]] -> [a] concat = proc {|xss| foldr[listJoin][[]][xss] } # concatMap :: (a -> [b]) -> [a] -> [b] concatMap = proc {|f| funcComp[concat][map[f]] } # head :: [a] -> a head = proc {|x| if x==[] then error["Prelude.head: empty list"] else x[0] end}