Kinds of bugs that are more likely/prone in Haskell programs than in other languages?

后端 未结 3 568
故里飘歌
故里飘歌 2021-02-14 17:40

One of the highly-touted features is that if a program compiles, it highly likely to be mostly correct, more so than a program written in a language with a less sophisticated or

相关标签:
3条回答
  • 2021-02-14 18:26

    Laziness, especially lazy I/O where pure functions can force IO actions or closing a file Handle prior to reading. The Haskell course by Stanford University has good information on this in the Iteratee lecture. Imho, this lecture series is very well written and covers a lot of ground.

    0 讨论(0)
  • 2021-02-14 18:35

    It doesn’t have to be asymptotic, but space leaks due to lazyness are a problem in real-world applications of Haskell. I know of Haskell-using companies that completely switched to strict datatypes (while still using the laziness of function parameters).

    For sources on that view, see:

    • E. Hesselink. Silk: making the sematic web functional. Functional Programming Exchange 2012, London, March 2012.
    • C. J. Sampson. Experience report: Haskell in the ’real world’: writing a commercial application in a lazy functional lanuage. In ICFP ’09, pages 185–190, 2009.
    • S. Wehr. Kommerzielle Softwareentwicklung mit Haskell. Hal6, Leipzig, Oct 2011. Slides (in German).
    0 讨论(0)
  • 2021-02-14 18:38

    Consider the following 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)
    

    I want to create a U Int with random values. It's easy using the Traversable instance:

    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
    

    Now I create a random infinite U Int and print the first three values of the list:

    randomInfiniteU :: U Int
    randomInfiniteU =  flip evalRand (mkStdGen 7) 
                     . T.sequence
                     $ U (repeat ri) ri  
    
    putStrLn . show $ take 3 $ (\(U l _) -> l) $ randomInfiniteU
    

    Works fine as well. As a last test, let's print the single value to the right:

    putStrLn . show $ (\(U _ i) -> i) $ randomInfiniteU
    

    Ugh. This hangs.

    0 讨论(0)
提交回复
热议问题