我试图在Haskell中学习IO,我发现它非常混乱。在 “使用decodeByName
:“ 下浏览了cassava
documentation on hackage
{-# LANGUAGE OverloadedStrings #-}
import Control.Applicative
import qualified Data.ByteString.Lazy as BL
import Data.Csv
import qualified Data.Vector as V
data Person = Person
{ name :: !String
, salary :: !Int
}
instance FromNamedRecord Person where
parseNamedRecord r = Person <$> r .: "name" <*> r .: "salary"
main :: IO ()
main = do
csvData <- BL.readFile "salaries.csv"
case decodeByName csvData of
Left err -> putStrLn err
Right (_, v) -> V.forM_ v $ \ p ->
putStrLn $ name p ++ " earns " ++ show (salary p) ++ " dollars"
字符串
我有两个问题
1.在Person
的声明中,他们用了!String
而不是String
,为什么?我用String
运行了同样的例子,结果没有什么不同。堆栈构建器网站上的教程也使用了!
。我在这里遗漏了什么?
1.在main函数中,
Right (_, v) -> V.forM_ v $ \ p ->
putStrLn $ name p ++ " earns " ++ show (salary p) ++ " dollars"
型
做什么?
我知道post $ \ p
是一个匿名函数,它将p
中的名称和p
中的salary
串联起来,显示salary
,因为它是一个整数。p
代表什么?它是一个元组,一个变量吗?他们是否使用p
作为Person
的数据结构?
表达式Right (_, v) -> V.forM_ v
的含义是什么?
1条答案
按热度按时间7gcisfzg1#
!
在一个类型被称为BangPattern
之前,它会导致参数在构造数据类型时被评估为弱头范式。非正式地说,它减少了懒惰的数量,在某些情况下会提高性能。Right (_, v) -> V.forM_ v $ \p -> ...
这部分模式匹配v
,它是一个Vector
行,在你的例子中是Person
类型。V.forM_
是一个来自vector
包的Monad m => Vector a -> (a -> m b) -> m ()
类型的函数。本质上,它对向量的每个元素执行一个一元操作,在你的例子中,Person -> IO ()
类型的IO
操作。因此,在本例中,p
是一个单独的Person
。