Haskell程序中比其他语言更容易/更容易出现的各种错误?

时间:2014-01-13 17:02:03

标签: haskell

高度吹捧的功能之一是,如果一个程序编译,它很可能大部分是正确的,比使用不太复杂或严格类型系统的语言编写的程序更为正确。

也就是说,Haskell是一个将运行时错误转换为编译器错误的系统: - )

我想知道,Haskell中的编程是否会导致程序员在一种不太强类型的语言中引入运行时错误而不具有明显模拟(外观和频率)的情况?

突然出现的一些基本例子:(不是很好,我正在寻找关于警惕的建议)

  • 由于懒惰导致的渐近性能错误
  • 由于错误结构的递归导致的无限循环
  • fundeps / type-families将逻辑推入类型级别,其中代码更“神秘”,错误更难发现?

陷阱的其他/更好的例子?

3 个答案:

答案 0 :(得分:7)

它不一定是渐近的,但是由于懒惰造成的空间泄漏是Haskell的实际应用中的一个问题。我知道使用Haskell的公司完全切换到严格的数据类型(同时仍然使用函数参数的懒惰)。

有关该视图的来源,请参阅:

  • 电子。海塞林克。丝绸:使sematic web功能齐全。功能编程Exchange 2012,伦敦,2012年3月。
  • ℃。 J.桑普森经验报告:Haskell在“现实世界”中:在懒惰的功能语言中编写商业应用程序。在ICFP '09,第185-190页,2009年。
  • S上。 WEHR。 Kommerzielle Softwareentwicklung mit Haskell。 Hal6,Leipzig,2011年10月。Slides(德语)。

答案 1 :(得分:4)

懒惰,尤其是懒惰的I / O,其中纯函数可以在读取之前强制IO操作或关闭文件HandleHaskell course by Stanford UniversityIteratee讲座中提供了很好的信息。 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

唉。这挂起了。