我試圖從https://haskell-at-work.com/episodes/2018-01-19-domain-modelling-with-haskell-data-structures.html中洗掉 Database.sh 檔案中的 do 符號
但我有一個錯誤,我不知道為什么。(可能只是意味著我不了解 Haskell)
這是Haskell 從 do notation 到 Applicative的延續
哈斯克爾代碼:
專案.hs
{-# LANGUAGE GeneralizedNewtypeDeriving #-}
module Project where
import Data.Text (Text)
newtype Money = Money
{ unMoney :: Double
} deriving (Show, Eq, Num)
newtype ProjectId = ProjectId
{ unProjectId :: Int
} deriving (Show, Eq, Num)
data Project
= Project ProjectId
Text
| ProjectGroup Text
[Project]
deriving (Show, Eq)
data Budget = Budget
{ budgetIncome :: Money
, budgetExpenditure :: Money
} deriving (Show, Eq)
data Transaction
= Sale Money
| Purchase Money
deriving (Eq, Show)
資料庫
import System.Random (getStdRandom, randomR)
import Project
getBudget :: ProjectId -> IO Budget
getBudget _ = Budget
<$> (Money <$> getStdRandom (randomR (0, 10000)))
<*> (Money <$> getStdRandom (randomR (0, 10000)))
getTransactions :: ProjectId -> IO [Transaction]
getTransactions _ =
let rtn = []
<$> (Sale . Money <$> getStdRandom (randomR (0, 4000)))
<*> (Purchase . Money <$> getStdRandom (randomR (0, 4000)))
in
pure rtn
錯誤
運行后stack ghc Database.hs --package random
Database.hs:12:13: error:
* Couldn't match expected type: Transaction -> Transaction -> b
with actual type: [a0]
* In the first argument of `(<$>)', namely `[]'
In the first argument of `(<*>)', namely
`[] <$> (Sale . Money <$> getStdRandom (randomR (0, 4000)))'
In the expression:
[] <$> (Sale . Money <$> getStdRandom (randomR (0, 4000)))
<*> (Purchase . Money <$> getStdRandom (randomR (0, 4000)))
* Relevant bindings include rtn :: f b (bound at Database.hs:12:7)
|
12 | let rtn = []
| ^^
uj5u.com熱心網友回復:
在
let rtn = []
<$> (Sale . Money <$> getStdRandom (randomR (0, 4000)))
<*> (Purchase . Money <$> getStdRandom (randomR (0, 4000)))
看起來您正在嘗試列出這兩個操作的結果?這不起作用,因為 的第一個引數(<$>)必須是一個函式,而[]不是一個函式(以及其他原因)。如果你想保留這個符號,你應該用一個配對函式替換:
pair x y = [x, y]
然后
let rtn = pair <$> ...
但我真的認為這里合適的組合器是sequenceA
sequenceA :: (Applicative f) => [f a] -> f [a]
它接受一個動作串列,并回傳一個回傳結果串列的動作。
所以:
let rtn = sequenceA [Sale . Money <$> getStdRandom (randomR (0, 4000)),
Purchase . Money <$> getStdRandom (randomR (0, 4000))]
哦,不應該有一個pure回傳這個。它已經是正確的型別,不需要提升到IO.
順便說一句,getStdRandom . randomR也稱為randomRIO.
轉載請註明出處,本文鏈接:https://www.uj5u.com/qianduan/462853.html
標籤:哈斯克尔
