2016-06-28 62 views
3

我想寫用下面的代碼Haskell的模塊更換記錄值:在Haskell

module RectangleMover where 

data Rectangle = Rectangle { xCoordinate :: Int 
          , yCoordinate :: Int 
          , width :: Int 
          , height :: Int 
          } deriving (Show) 

move :: Rectangle -> Int -> Int -> Rectangle 
-- Edit 1 
move rec x y = 
    let rec' = { xCoordinate + x 
       , yCoordinate + y 
       } 
    return rec 

要創建一個矩形i鍵入:

let rec = Rectangle 10 10 20 30 

但我的問題是,現在怎麼實現一個「移動」這個矩形的功能? 在C#或Java調用會是這樣的:rec.move(20,20); 但是怎麼會變成這樣寫在Haskell?

這是不幸的是我第一次嘗試用一個函數式編程語言...

編輯1: 我添加的代碼我的函數內但仍然獲得瞭解析錯誤「x座標+ X」 ...

+0

「move」作爲參數使用的兩個'Int'的含義是什麼?沿x軸和y軸偏移?還有別的嗎? – Jubobs

+0

是的x軸和y軸的偏移量 – ManzMoody

回答

4

你剛纔的偏移量添加到角落:

move :: Rectangle -> Int -> Int -> Rectangle 
move (Rectangle x y w h) dx dy = Rectangle (x + dx) (y + dy) w h 

隨着記錄語法,不過,你可以把它寫成

move :: Rectangle -> Int -> Int -> Rectangle 
move [email protected](Rectangle {xCoordinate = x, yCoordinate=y}) dx dy = r { 
    xCoordinate = x + dx, 
    yCoordinate = y + dy } 

更長,但只是因爲兩個領域的長名更新。你可能會進一步定義Point類型:

data Point = Point Int Int 
movePoint :: Point -> Int -> Int -> Point 
movePoint (Point x y) dx dy = Point (x + dx) (y + dy) 

data Rectangle = Rectangle { corner :: Point, width :: Int, height :: Int } 
move :: Rectangle -> Int -> Int -> Rectangle 
move [email protected](Rectangle {corner=c}) dx dy = r { corner = movePoint c dx dy } 
+0

當我嘗試用「點」的版本,我得到'錯誤:沒有範圍: :Int}'然後'出現'移動'的重複類型簽名。因此,我將第一個移動函數重命名爲'movePoint',現在我得到'無法匹配預期類型'Int' ,實際類型爲'Point - > Int' ' ' – ManzMoody

+0

我改成了'數據點=點{X ::詮釋,Y: – ManzMoody

+0

對不起, trygub修復了它。我不確定是否使用'Point'類型的記錄語法,並且會寫出破碎的混合記錄和非記錄語法。 – chepner

5

Haskell的值是不可改變的,所以你要返回一個新Rectangle與修改所需的性能。這很簡單,用「更新記錄語法」這樣let myNewRec = rec { yCoordinate = 20, xCoordinate = 20 }

+0

但是我可以在我的「移動」功能塊中使用這種語法嗎?或者如何寫?如你所說,我需要創建一個新的矩形,並從「移動」功能返回這個新的矩形,對吧? – ManzMoody

+0

我改變代碼上述(編輯1),但我仍然在 「x座標+ X」 – ManzMoody

+2

'移動::矩形得到解析錯誤 - >內部 - >內部 - > Rectangle'和'移動REC XY = {REC = xCoodinate x,yCoodinate = y}'。你可以在沒有記錄名的情況下這樣做:'move(Record _ _ w h)x y =記錄x y w h'。在第一行類型變量「x'' ... –

5

鑑於這是你第一次與哈斯克爾,去與已經提到的記錄更新的答案。但是,對於未來用戶使用Google,以及對於您來說,如果您感覺更加雄心勃勃(或爲了將來的學習),Haskell有這個非常流行且功能非常強大的庫,名爲lens

這裏是你如何使用工程師到您問題的解決方案。

{-# LANGUAGE TemplateHaskell #-} 
import Control.Lens 

data Rectangle = Rectangle { _xCoordinate :: Int 
          , _yCoordinate :: Int 
          , _width :: Int 
          , _height :: Int 
          } deriving (Show) 
makeLenses ''Rectangle 

move :: Rectangle -> Int -> Int -> Rectangle 
move rect dx dy= rect 
        & xCoordinate +~ dx 
        & yCoordinate +~ dy 

該解決方案似乎並不更強大最初,但是當你開始嘗試更新嵌套的記錄,我向你保證的優勢變得清晰。