以下代码应该生成一个按钮,按下该按钮会创建一个框(以及一个用于删除其上框的按钮)
import Graphics.Input
import Signal (..)
import Signal
import Mouse
import Text (Text, asText, plainText)
import Graphics.Element (..)
import Graphics.Collage (..)
import Color (..)
import List
import Dict
-- x y id | id
type Event = Add (Float, Float, Int) | Remove (Int) | Maybe
makebox : Int -> Element
makebox id =
let (w, h) = (30, 30)
in flow down
[ layers [plainText "aaaa", collage w h [square 30 |> filled red]]
, button_remove id ]
add = Signal.channel (0,0,0)
remove = Signal.channel (0)
button_add x y = Graphics.Input.button (Signal.send add (x, y, 2)) "add a box"
button_remove id = Graphics.Input.button (Signal.send remove (id)) "remove me"
main =
let update event =
case event of
Add (x, y, id) -> Dict.insert id ((x,y), ((makebox id)))
Remove (id) -> Dict.remove id
Maybe -> identity
in Signal.map (\dict -> flow down
[ button_add 10.0 20.0 --makes add & remove buttons
, collage 500 500 (List.map (\(Just ((x,y), makebox)) -> move (x,y) makebox)
(Dict.values dict)) --draws the dict
]) --map function argument
(foldp update Dict.empty
(merge
(Add <~ (Signal.subscribe add)) --pipes button channels into events
(Remove <~ (Signal.subscribe remove)))) --map signal argument
但是,它会产生此类错误:
Type mismatch between the following types on line 40, column 14 to 20:
((Int, Int))
Maybe.Maybe
It is related to the following expression:
update
我不知道这个错误来自哪里,Maybe.Maybe传递到update
的哪个位置,我该如何解决?
答案 0 :(得分:1)
查找&amp;将collage
中的main
来电替换为此行:
, collage 500 500 (List.map (\((x,y), makebox) -> move (x,y) (toForm makebox))
这是很多代码。我不得不改变风格,理解它是如何工作的。我所做的是将更多的功能移到顶层并给它们输入类型注释。我还将button_add
/ remove
更改为camelCase,因为这是标准的Elm命名约定。这是结果:
import Graphics.Input
import Signal (..)
import Signal
import Mouse
import Text (Text, asText, plainText)
import Graphics.Element (..)
import Graphics.Collage (..)
import Color (..)
import List
import Dict
-- x y id | id
type Event = Add (Float, Float, Int) | Remove (Int) | Maybe
type alias Model = Dict.Dict Int ((Float,Float), Element)
makebox : Int -> Element
makebox id =
let (w, h) = (30, 30)
in flow down
[ layers [plainText "aaaa", collage w h [square 30 |> filled red]]
, buttonRemove id ]
add : Signal.Channel (Float,Float,Int)
add = Signal.channel (0,0,0)
remove : Signal.Channel Int
remove = Signal.channel 0
buttonAdd : Float -> Float -> Element
buttonAdd x y = Graphics.Input.button (Signal.send add (x, y, 2)) "add a box"
buttonRemove : Int -> Element
buttonRemove id = Graphics.Input.button (Signal.send remove id) "remove me"
update : Event -> Model -> Model
update event =
case event of
Add (x, y, id) -> Dict.insert id ((x,y), makebox id)
Remove (id) -> Dict.remove id
Maybe -> identity
-- move' : Just ((Float,Float),Element) -> Form
move' (Just ((x,y), makebox)) = move (x,y) makebox
view : Model -> Element
view dict =
flow down
[ buttonAdd 10.0 20.0 --makes add & remove buttons
, collage 500 500 (List.map move' (Dict.values dict)) --draws the dict
]
input : Signal Event
input = merge
(Add <~ (Signal.subscribe add)) --pipes button channels into events
(Remove <~ (Signal.subscribe remove))
model : Signal Model
model = foldp update Dict.empty input
main : Signal Element
main = view <~ model
我们仍然得到相同的,不是非常有用的类型错误。但现在它在move'
功能上。我在评论中添加了我想到的类型签名。
这段代码有两个问题:
move'
获取Element
(除其他外)并尝试move
,但move
适用于Form
。因此,在它工作之前需要调用toForm
。Dict.values
提供值列表,而不是Just
值列表(类型Maybe.Maybe
)。 因此,解决方案是move'
函数,如下所示:
move' : ((Float,Float), Element) -> Form
move' (a,b) = move a (toForm b)