我正在尝试在 haskell 中学习 IO,我发现它非常令人困惑..浏览了 hackage 的文档
https://hackage.haskell.org/package/cassava使用decodebyName
{-# 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"
我有两个问题
在针对名称的 Person 声明中,他们使用“!String”而不是 String ..为什么?我使用“String”运行了相同的示例,输出没有任何差异。堆栈构建器网站上的教程也使用“!”..我在这里缺少什么?
main函数中做什么
putStrLn $ name p ++ " earns " ++ show (salary p) ++ " dollars"
做什么?
我知道 post $ \ p 是一个匿名函数,它放置一个新字符串,连接 p 中的名称和 p 中的薪水,显示薪水,因为它是一个 int ..
p 代表什么?它是一个元组,一个变量吗?他们使用 p 作为 Person 数据结构吗?
Right (_, v) -> V.forM_ v
这个表达是什么意思?
!
称为 BangPattern
,它会导致在构造数据类型时将参数评估为弱头范式。通俗地说,它减少了懒惰的程度,在某些情况下这会提高性能。
Right (_, v) -> V.forM_ v $ \p -> ...
此部分模式与 v
匹配,在您的类型为 Vector
的情况下,它是 Person
行。 V.forM_
是来自 Monad m => Vector a -> (a -> m b) -> m ()
包的
vector
类型的函数。本质上,它对向量的每个元素执行一个单子操作,在您的例子中,是一个类型为 IO
的 Person -> IO ()
操作。所以在这种情况下,p
是一个个体Person
。