Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Expression eager in Frege but lazy in Haskell?

Tags:

haskell

frege

In Haskell, the following code prints "[1,2,3,4,5":

foo = take 10 $ show $ numbersFrom 1 where 
  numbersFrom start = start : numbersFrom (start + 1) -- could use [1..]

But in Frege, It throws OutOfMemoryError with the following code:

foo = take 10 $ unpacked $ show $ numbersFrom 1 where
  numbersFrom start = start : numbersFrom (start + 1)

Here the only difference is the unpacked function which is necessary to convert from String to [Char] and FWIW, the unpacked function is eager. Why can't the whole expression be lazy as in Haskell? Is it possible to achieve something similar to Haskell in Frege here?

like image 693
Marimuthu Madasamy Avatar asked Aug 15 '12 01:08

Marimuthu Madasamy


2 Answers

I don't know Frege, but according to the language definition String is java.lang.String so you can't build infinitely long strings (the out of memory issue probably has nothing to do with unpack being eager).

Because you know each element of numbersFrom 1 will be shown as at least 1 character then you can over-approximate the size of the list to show then unpack, then take the number of desired characters:

foo = take 10 $ unpacked $ show $ take 10 $ numbersFrom 1 where
  numbersFrom start = start : numbersFrom (start + 1)

Or more generally:

n = 10 -- number of characters to show
m = 1  -- minimum (map (length . show) xs) for some type of xs
foo :: a -> [Char]
foo = take n . unpack . show . take ((n+m-1) `div` m) . someEnumeration
  where
  someEnumeration :: a -> [a]
  someEnumeration = undefined

If your enumeration is expensive then you can start taking into account the number of commas, whitespace, etc and reduce the argument to the second take, but you get the idea.

like image 125
Thomas M. DuBuisson Avatar answered Oct 04 '22 08:10

Thomas M. DuBuisson


I haven’t used Frege, but it seems to me that if unpacked is strict, then its argument ought not be an infinite list. Try unpacked $ take 10 instead of take 10 $ unpacked.

like image 28
Jon Purdy Avatar answered Oct 04 '22 07:10

Jon Purdy