为什么case表达式在这个Elm代码中不起作用?

时间:2015-07-14 03:24:29

标签: syntax pattern-matching elm

我写了一个Elm代码片段,它会绘制一个正方形,并在每次点击鼠标时更改红色和黑色之间的方形颜色。

然而 changeColor 功能中的 case 结构无法正常工作,而 changeColor 使用实现 strong>结构将起作用。

我该怎么做才能弄清楚出了什么问题?谢谢。

import Color exposing (red, black, blue, Color)
import Signal exposing ((<~))
import Graphics.Element exposing (Element, show)
import Graphics.Collage exposing (collage, square, filled, Form)
import Mouse
import Window

main : Signal Element
main = 
  scene <~ (Signal.foldp changeColor black Mouse.clicks)

scene : Color -> Element
scene color = 
  collage 600 600 [ filled_square color ]

changeColor : () -> Color -> Color
changeColor _ color =
  case color of
    black -> red
    red -> black

--changeColor _ color =
--  if | color == black -> red
--     | color == red -> black

filled_square : Color -> Form
filled_square color = square 100 |> filled color

1 个答案:

答案 0 :(得分:4)

模式变量(简答)

案例模式中的小写名称始终被视为变量,永远不会是常量。因此,您的case语句将匹配模式变量black的颜色,该模式变量成功,并将名称black绑定到案例分支(color)内的-> red值。

在这种情况下,您在评论中使用的多方if是区分案例的适当方式。

使用案例表达式

案例表达用于区分union types中的案例。例如,您可以使用类似的联合类型显式建模程序状态:

import Color exposing (red, black, blue, Color)
import Signal exposing ((<~))
import Graphics.Element exposing (Element, show)
import Graphics.Collage exposing (collage, square, filled, Form)
import Mouse
import Window

type Model = Red | Black

main : Signal Element
main = 
  scene <~ (Signal.foldp changeColor Black Mouse.clicks)

scene : Model -> Element
scene model = 
  collage 600 600 [ filled_square (toColor model) ]

toColor : Model -> Color
toColor model =
  case model of
    Black -> black
    Red -> red

changeColor : () -> Model -> Model
changeColor _ model =
  case model of
    Black -> Red
    Red -> Black

filled_square : Color -> Form
filled_square color = square 100 |> filled color

这样做的原因可能是您现在在一个易于查找的地方拥有有限的,可枚举的状态。如果你只使用颜色,你只能通过查看整个程序来确定这一点。 case表达式是详尽无遗的,它处理你的程序可以处于的所有状态。而对于多种颜色,如果在颜色上,谁知道这些是你的程序中可能有的唯一颜色,特别是一旦它变得比玩具更大 - 例如-尺寸。如果您没有匹配所有可能的颜色,则可能会遇到应用程序的运行时崩溃。 (这是榆树可能发生的几种可能方式之一)