我正在研究這個程序,以更好地理解haskell和state monad。我做了一個模塊Rectangle,它具有數據類型Rectangle和一個函數來增加矩形的長度。爲了增加長度,我做了一個函數加。 難道還有比這個加功能更好的方法嗎?同時增加我正在添加一個新的矩形,這是邏輯上不正確的。 如何以正確的方式執行增量?有沒有什麼辦法,而不是給予默認寬度編譯器提示用戶的寬度? 如何在進行有狀態計算時提取一個或多個矩形或任何屬性(長度或寬度)?實現遞增函數
{-# LANGUAGE TemplateHaskell, TypeOperators #-}
module Rectangle(Rectangle(Rectangle),GlobState(GlobState),plus,newGlobState,r1,r2,r3,incr) where
import Control.Monad.State hiding (modify)
import Data.Label (mkLabels)
import Data.Label.Pure ((:->))
import Data.Label.PureM
type Length = Int
type Width = Int
data Rectangle = Rectangle Length Width deriving (Eq,Read,Show)
data GlobState = GlobState { _r1 :: Rectangle , _r2 :: Rectangle , _r3 :: Rectangle } deriving Show
$(mkLabels [''GlobState])
plus :: Rectangle -> Rectangle -> Rectangle
plus (Rectangle x z) (Rectangle y w) = Rectangle (x+y) z
newGlobState:: GlobState
newGlobState = GlobState { _r1 = Rectangle 0 10, _r2 = Rectangle 0 10, _r3 = Rectangle 0 10}
incr :: (GlobState :-> Rectangle) -> State GlobState()
incr x = modify x (plus (Rectangle 1 10))
我做了一個新的模塊選擇矩形的一個:
{-# LANGUAGE TemplateHaskell, TypeOperators #-}
module ChooseRect(ChooseRect(ChooseRect),makeChoice,select) where
import Rectangle
import Control.Monad.State hiding (modify)
import Data.Label (mkLabels)
import Data.Label.Pure ((:->))
import Data.Label.PureM
type Choice = Int
data ChooseRect = ChooseRect Rectangle Rectangle deriving Show
makeChoice:: Rectangle-> Rectangle->ChooseRect
makeChoice p1 p2 = ChooseRect p1 p2
select:: ChooseRect -> Choice -> Rectangle
select (ChooseRect (Rectangle x z) (Rectangle y w)) choice = if (choice==1)
then let selectedRectangle = Rectangle x z
in selectedRectangle
else let selectedRectangle = Rectangle y w
in selectedRectangle
但是,當我更改了主模塊I M得到錯誤。
module Main where
import Rectangle
import ChooseRect
import Control.Monad.State hiding (modify)
import Data.Label (mkLabels)
import Data.Label.Pure ((:->))
import Data.Label.PureM
main :: IO()
main = do
let x = flip execState newGlobState $ do
incr r1
incr r2
incr r1
incr r3
incr r3
let y=makeChoice r1 r2
print y
print x
的錯誤消息是
Couldn't match expected type `Rectangle'
with actual type `Data.Label.Abstract.Lens
(~>0) GlobState Rectangle'
In the first argument of `makeChoice', namely `r1'
In the expression: makeChoice r1 r2
In an equation for `y': y = makeChoice r1 r2
請解釋錯誤,以及如何將其刪除
是否有意讓您的'incr'強制矩形的寬度爲10? (現在所有的矩形都有10的寬度,但是如果例如'r3'開始爲'Rectangle 0 5',你真的需要'incr'來使它成爲'Rectangle 1 10'嗎?) – dave4420 2012-02-01 10:14:52
沒有..我想它是矩形1 5.這就是爲什麼我問我如何讓用戶輸入寬度 – 2012-02-01 10:17:51
因此,不僅是'加號'邏輯不正確的類型,它也隱藏了一個錯誤。 – dave4420 2012-02-01 10:32:47