I've been going through SICP, first in Scheme and then in Haskell, and I started wondering...
Is my Haskell too Lisp-y?
filterAccumulate
:: (Eq t1) =>
(t1 -> Bool) -> (t2 -> t3 -> t3) -> t3 -> (t1 -> t2) -> t1 -> (t1 -> t1) -> t1 -> t3
filterAccumulate filter combiner nullVal term a next b =
iter a nullVal
where
iter a result =
if (a == b) then filterCombiner a result
else iter (next a) (filterCombiner a result)
filterCombiner a result =
if (filter a) then combiner (term a) result
else result
>>4
I've started using type signatures in Scheme as well. Even if they don't act as constraints, they can clear things up a bit. But I wouldn't even know how to start using monadic idioms in Scheme.
Anyway, maybe this soothes the Haskell soul a bit: myAccumulate = filterAccumulate (const True)
I also decided to do the rational numbers. -- Section 2.1.1
makeRational n d =
(n2 `div` g, d2 `div` g)
where
g = gcd n d
n2 = (abs n) * (sign $ n `div` d)
d2 = abs d
sign n | (n < 0) = -1
| otherwise = 1
numerator = fst
denominator = snd
addRational x y =
makeRational ((cm x y) + (cm y x))
(((*) `on` denominator) x y)
where cm a b = (numerator a) * (denominator b)
showRational r = do
putStrLn ((show $ numerator r) ++ "/" ++ (show $ denominator r))
Name:
Anonymous2010-03-26 14:26
SICP's crazy fucked-up method of cons-ing counting numbers:
cons a b = (2^a)*(3^b)
car = fromCounting 2
cdr = fromCounting 3
fromCounting t p =
iter 0 p
where
iter a p = if r /= 0 then a
else iter (a+1) q
where (q,r) = p `divMod` t let foo = cons 1 4
foo foo
162 car foo
1 cdr foo
4 let bar = cons 5 foo
bar bar
6292065615217693235778429072861187721059310430214872541674093297214924518297888 car bar
5 car (cdr bar)
1 cdr (cdr bar)
4
Just blew my fuckin' mind. I'm referring, of course, to Haskell's handling of large numbers. PLT Scheme would have had an aneurysm.
>>7 PLT Scheme would have had an aneurysm.
HIBT? My naive translation works fine in PLT, and in Ikarus if I change (require srfi/8 srfi/26) to (import (srfi :8) (srfi :26)) and (define quotient/remainder div-and-mod). Scheme's numeric tower has been excellent for a long time. R5RS says Implementations are encouraged, but not required, to support exact integers and exact rationals of practically unlimited size and precision, but I believe R6RS made it a hard requirement. I found out when plotting some Julia sets that PLT even supports unlimited size and precision for complex numbers which meant I had to force it do inexact arithmetic to speed things up :) (require srfi/8 srfi/26)
(define (cons a b)
(* (expt 2 a)
(expt 3 b)))
(define (fromCounting t p)
(let iter ((a 0) (p p))
(receive (q r) (quotient/remainder p t)
(if (zero? r)
(iter (add1 a) q)
a))))
(define car (cut fromCounting 2 <>))
(define cdr (cut fromCounting 3 <>))
>>8
I should say probably say what those SRFIs are.
SRFI 8 is receive, which is just a macro around call-with-values. IIRC R6RS standardised let-values, but that looks ugly when you want to get the values of one expression, which, for me anyway, is the common case.
SRFI 26 provides cut and cute which are just macros for specialising functions. It works out much nicer than having to explicitly write the lambdas or currying you scheme code.
Name:
Anonymous2010-03-26 15:24
Real programmers can programm FORTRAN in ever language.
-> only way to fix lisp and haskell.
Name:
Anonymous2010-03-26 15:29
>>8
I defined it a little differently, and it may in fact be buggy.
(define (from-counting-pair t p)
(define (iter a p)
(if (= (remainder p t) 0)
(iter (+ a 1) (quotient p t))
a))
(iter 0 p))
At the very least it's less efficient because it does remainder and quotient separately. I didn't know that there is a pattern matching form receive in Scheme.
>>12
Yes you did and the chaos escaped from the eve.
Name:
Anonymous2010-03-26 21:31
C / Perl / occasional Lisp programmer here. Am I the only person who doesn't get the fucking point of Haskell? True, I have little knowledge of the underlying syntax of the language, but from various discussions I've read here and on /code/, I just don't understand how in the hell a Haskell program is supposed to resemble a computer program. I can programs made in various languages, even Lisp, and easily recognize after a few seconds ``oh, that's what it does. I'm guessing when translated/compiled it would look something like blah blah blah.'' When I try to make any kind of sense out of a Haskell program, I feel like I'm trying to program on a mushroom.
>>15
I think if you add Erlang to your list you'll quickly see the point of Haskell. This is what I've been told anyway, when I asked for another Erlang. (Don't get me wrong, Erlang is dandy.)
Name:
Anonymous2010-03-26 22:45
>>15
Haskell lets you represent programs more clearly and beautifully than any other language. Then it goes beyond that and lets you represent them in a more obfuscated and incomprehensible fashion than any other language, while still retaining the fundamental beauty and simplicity.
Name:
Anonymous2010-03-27 1:44
>>15
If you don't understand what Haskell is up to, you don't know Lisp well enough. Unless the part you don't get is why all the syntax. That's just because Haskeller's are nuts.