高度吹捧的功能之一是,如果一个程序编译,它很可能大部分是正确的,比使用不太复杂或严格类型系统的语言编写的程序更为正确。
也就是说,Haskell是一个将运行时错误转换为编译器错误的系统: - )
我想知道,Haskell中的编程是否会导致程序员在一种不太强类型的语言中引入运行时错误而不具有明显模拟(外观和频率)的情况?
突然出现的一些基本例子:(不是很好,我正在寻找关于警惕的建议)
陷阱的其他/更好的例子?
答案 0 :(得分:7)
它不一定是渐近的,但是由于懒惰造成的空间泄漏是Haskell的实际应用中的一个问题。我知道使用Haskell的公司完全切换到严格的数据类型(同时仍然使用函数参数的懒惰)。
有关该视图的来源,请参阅:
答案 1 :(得分:4)
懒惰,尤其是懒惰的I / O,其中纯函数可以在读取之前强制IO
操作或关闭文件Handle
。 Haskell course by Stanford University在Iteratee
讲座中提供了很好的信息。 Imho,这个系列讲座写得很好,涵盖了很多方面。
答案 2 :(得分:1)
考虑以下dataype:
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE DeriveFoldable #-}
{-# LANGUAGE DeriveTraversable #-}
import Data.Foldable
import qualified Data.Traversable as T
import Control.Monad.Random
data U a = U [a] a deriving (Show,Functor,Foldable,T.Traversable)
我想用随机值创建U Int
。使用Traversable
实例很容易:
ri :: Rand StdGen Int
ri = getRandomR (0,3)
randomU :: U Int
randomU = flip evalRand (mkStdGen 7)
. T.sequence
$ U (replicate 3 ri) ri
putStrLn . show $ randomU -- works
现在我创建一个随机无限U Int
并打印列表的前三个值:
randomInfiniteU :: U Int
randomInfiniteU = flip evalRand (mkStdGen 7)
. T.sequence
$ U (repeat ri) ri
putStrLn . show $ take 3 $ (\(U l _) -> l) $ randomInfiniteU
也可以正常工作。作为最后一次测试,让我们打印右边的单个值:
putStrLn . show $ (\(U _ i) -> i) $ randomInfiniteU
唉。这挂起了。