【问题标题】:Elm signals and type annotationElm 信号和类型注释
【发布时间】:2014-11-03 06:26:15
【问题描述】:

来自 Elm 新手但长期使用 Haskeller,快速查询。

目的:有一张地图,上面指定位置有城镇,我想检查用户点击是否靠近城镇,并识别出那个城镇。

所以,我照常收集信号:

clickPositionsSignal = sampleOn Mouse.clicks Mouse.position

这给了我一个元组,我想把它变成一个 Int(表示最近城镇的编号)。城镇被指定为

positions : [Position] 
type Position = {number : Int, x : Int, y : Int}

这样做的功能是:

whichTown : (Int,Int) -> Int
whichTown (x,y) = 
            let pz = map (\p -> getDistance p.x p.y x y) positions |> head
            in pz.number

现在,我需要将此函数应用于我的 clickPositionsSignal。

查看各种示例,我修改了一些代码以......

whichLocationSignal : Signal Int
whichLocationSignal =           
      let wbl (x,y) = whichTown(x,y)
      in wbl <~ clickPositionsSignal

....这行得通。我得到最近城镇的号码。

但这是无可救药的麻烦和重复。问题是为什么我不能简单地写:

whichLocationSignal = whichTown clickPositionsSignal

该行引发了多个类型错误,我还没有足够的经验来解释

【问题讨论】:

  • whichBoardPosition 函数长什么样子?
  • 抱歉,忘记将最后 2 个代码块中的函数从“whichBoardPosition”重命名为“whichTown”。上面编辑过的代码。
  • 啊。很简单:whichTown
  • 是的,没错!就像你在 Haskell 中使用 whichTown &lt;$&gt; clickPositionsSignal 一样,如果 SignalFunctor

标签: signals elm


【解决方案1】:

TL;DR

应该是:

whichLocationSignal = whichTown <~ clickPositionsSignal

whichLocationSignal = lift whichTown clickPositionsSignal

(你自己已经弄清楚了)

如何读取类型错误

因此,给出这些类型错误的完整版本的代码将是:

import Mouse

type Position = {number : Int, x : Int, y : Int}

clickPositionsSignal : Signal (Int,Int)
clickPositionsSignal = sampleOn Mouse.clicks Mouse.position

positions : [Position]
positions = []

getDistance x1 y1 x2 y2 = { number = 0 }

whichTown : (Int,Int) -> Int
whichTown (x,y) = 
  let pz = map (\p -> getDistance p.x p.y x y) positions |> head
  in pz.number

whichLocationSignal : Signal Int
whichLocationSignal = whichTown clickPositionsSignal

然后我得到的类型错误是:

Type error on line 19, column 33 to 53:
     clickPositionsSignal

  Expected Type: (Int, Int)
    Actual Type: Int

Type error on line 19, column 33 to 53:
     clickPositionsSignal

  Expected Type: Signal.Signal
    Actual Type: (Int)

Type error on line 19, column 23 to 32:
     whichTown

  Expected Type: Int
    Actual Type: Signal.Signal Int

我承认,这些类型错误令人困惑。
(您甚至可能会说它们是不正确的。我只能说这是您得到的当前类型错误的质量,抱歉!)
当来自 Elm 的类型错误没有意义时,一个基本提示是看看当你翻转预期/实际时它是否更有意义。那么第一种类型的错误就没有意义了。但第二个提供了一些信息:clickPositionsSignal 以某种方式被期望有一个类型Int,而不是一些Signal。与第三条错误消息一起,这开始变得有意义:whichTown 在应该给出 Int 但你得到 Signal...
此时您可以找到这两者的用法,并且一旦您注意到whichTown 可以在(Int,Int)clickPositionsSignal : Signal (Int,Int) 上工作,您就会发现错误并且编译器消息具有某种歪曲的意义。

上述修复方法是使用lift : (a -&gt; b) -&gt; Signal a -&gt; Signal b 将函数(whichTown)“提升”到Signal“级别”。大多数人更喜欢使用中缀运算符&lt;~

【讨论】:

  • 感谢您的额外说明。预期/实际类型错误似乎(如您所见)与我在 Haskell 中所期望的相反,这确实让我感到困惑。
猜你喜欢
  • 1970-01-01
  • 2015-02-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-08-30
  • 2019-05-06
相关资源
最近更新 更多