I've been using Haskell on and off for a few years and have written a few (small) projects in it. Every time I end up turned off of it, though. First, I don't like how it makes side effects such a PITA. Fact of the matter is, computing is only useful for the side effects. A computation is useless if the result isn't printed to the screen, saved to a file, sent over the network, or used in some other way. So why make…
Why Not Haskell?
131–134 of 134 posts
Re: Why Not Haskell?
#132Earlier quoted context omitted.
OK, so we were learning about greedy algorithms at school and I implemented a very naive implementation of a change making algorithm for Canadian coins. Here's the Haskell code: makeChange :: Int -> [Int] makeChange amount = loop 0 [200, 100, 25, 10, 5, 1] [] where loop total coins@(c:cs) solution | total == amount = solution | null coins = error "no solution" | otherwise = if total + c > amount then loop total cs so…
quickcheck is running makeChange with an arbitrary Int. maxBound :: Int here is 2147483647. When given a number that large, makeChange recurses a lot, subtracting one two-dollar coin at a time, so you blow the stack. This is where you need to consult a haskell guru to find a way to make your code tail-recursive -- or find a smarter algorithm (using mod c for example so it only needs to recurse 6 times total). Amusing…
Re: Why Not Haskell?
#133Earlier quoted context omitted.
OK, so we were learning about greedy algorithms at school and I implemented a very naive implementation of a change making algorithm for Canadian coins. Here's the Haskell code: makeChange :: Int -> [Int] makeChange amount = loop 0 [200, 100, 25, 10, 5, 1] [] where loop total coins@(c:cs) solution | total == amount = solution | null coins = error "no solution" | otherwise = if total + c > amount then loop total cs so…
quickcheck is running makeChange with an arbitrary Int. maxBound :: Int here is 2147483647. When given a number that large, makeChange recurses a lot, subtracting one two-dollar coin at a time, so you blow the stack. This is where you need to consult a haskell guru to find a way to make your code tail-recursive -- or find a smarter algorithm (using mod c for example so it only needs to recurse 6 times total). Amusing…
It runs just fine on my box with i = 2^32: 10s to completion or thereabouts.
However, the way this is written, the code has to construct the entire list in memory before it can print any of it out so for larger lists it is pretty much guaranteed to blow the stack and / or memory depending on the computational representation.
If it was using a snoclist or something then it could stream the output and perform the calculation in constance space, as it stands it has to hold on to the whole list of integers before outputting any of them.
I'm surprised that the OCaML version 'just worked' frankly: either a) the OP didn't use QuickCheck with their OCaML code or b) the OCaML QuickCheck doesn't bother testing across the whole Int space.
Re: Why Not Haskell?
#134Earlier quoted context omitted.
quickcheck is running makeChange with an arbitrary Int. maxBound :: Int here is 2147483647. When given a number that large, makeChange recurses a lot, subtracting one two-dollar coin at a time, so you blow the stack. This is where you need to consult a haskell guru to find a way to make your code tail-recursive -- or find a smarter algorithm (using mod c for example so it only needs to recurse 6 times total). Amusing…
It's even worse than that if he's on a 64-bit machine! It runs just fine on my box with i = 2^32: 10s to completion or thereabouts. However, the way this is written, the code has to construct the entire list in memory before it can print any of it out so for larger lists it is pretty much guaranteed to blow the stack and / or memory depending on the computational representation. If it was using a snoclist or somethin…