表达在弗雷格的渴望,但在哈斯克尔懒惰?

Mar*_*amy 6 haskell frege

在Haskell中,以下代码打印"[1,2,3,4,5":

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

但在弗雷格,它抛出OutOfMemoryError以下代码:

foo = take 10 $ unpacked $ show $ numbersFrom 1 where
  numbersFrom start = start : numbersFrom (start + 1)
Run Code Online (Sandbox Code Playgroud)

这里唯一的区别是unpacked转换String[Char]和FWIW所需的unpacked功能,功能是急切的.为什么整个表达式不能像Haskell一样懒惰?是否有可能在弗雷格实现与Haskell相似的东西?

Tho*_*son 7

我不知道弗雷格,但根据语言的定义Stringjava.lang.String这样,你不能建立无限长的字符串(内存不足问题可能有无关,与unpack被渴望).

因为您知道每个元素numbersFrom 1将显示为至少1个字符,那么您可以过度估计列表的大小以显示然后解压缩,然后获取所需字符的数量:

foo = take 10 $ unpacked $ show $ take 10 $ numbersFrom 1 where
  numbersFrom start = start : numbersFrom (start + 1)
Run Code Online (Sandbox Code Playgroud)

或者更一般地说:

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
Run Code Online (Sandbox Code Playgroud)

如果你的枚举很昂贵,那么你可以开始考虑逗号,空格等的数量,并将参数减少到第二个take,但你明白了.


Jon*_*rdy 6

我没有使用弗雷格,但在我看来,如果unpacked是严格的,那么它的论点不应该是无限的列表.尝试unpacked $ take 10而不是take 10 $ unpacked.

  • 弗雷格的字符串不是列表.所以`take 10`不能应用于`show`的结果.因此`unpacked`用于首先从`String`转换为`[Char]`然后在列表中应用`take 10`. (3认同)
  • 那么什么是弗雷格的'String`s?看起来它们是`java.lang.String`(参见Frege语言定义).你将永远无法评估`unpack`,因为它永远无法构建字符串! (3认同)