gpt4 book ai didi

elm - 使用 foldp 折叠多个信号

转载 作者:行者123 更新时间:2023-12-01 00:56:11 24 4
gpt4 key购买 nike

我正在尝试将 foldp 与结合两个信号的输入函数的结果一起使用。

这是我的代码。

import Graphics.Element (..)
import Graphics.Collage (..)
import Color (..)
import Signal
import Keyboard
import Text (asText)
import Time (..)

-- Display
render : (Int, Int) -> Element
render (xDiff, yDiff) = collage 200 200 [
rotate (degrees (toFloat yDiff))
(filled blue (ngon 5 (10 * toFloat xDiff))) ]

-- Combine two signals to be a pair
input = Signal.map2 (,) (fps 25) Keyboard.arrows

-- Fold past combined signals from input and pass resulting signal to render
main : Signal Element
main = Signal.map render
(Signal.foldp (\dir (upd, {x, y}) ->
(x + dir.x, y + dir.y)) (0,0) input)

-- Fold past Keyboard.arrows and pass resulting signal to render
--main : Signal Element
--main = Signal.map render
-- (Signal.foldp (\dir (x, y) ->
-- (x + dir.x, y + dir.y)) (0,0) Keyboard.arrows)

我得到的错误:
Type mismatch between the following types on line 34, column 55 to 60:
(Float, { x : Int, y : Int })

{ a | x : Int, y : number }

It is related to the following expression:

input

Type mismatch between the following types on line 34, column 26 to 46:

{ a | x : Int, y : number }

number

Looks like something besides an Int or Float is being used as a number.
It is related to the following expression:

(x + dir.x,y + dir.y)

Type mismatch between the following types on line 34, column 26 to 46:

Int

{ a | x : number, y : number }

It is related to the following expression:

(x + dir.x,y + dir.y)`

在 main 中,我可以用 asText 替换渲染并得到类似的错误,所以我认为即使渲染处理输入可能存在问题,我认为我与 foldp 一起使用的函数也存在问题。

最佳答案

TL; 博士

这是 main 的正确代码:

main : Signal Element
main = Signal.map render
(Signal.foldp (\(upd, dir) (x, y) ->
(x + dir.x, y + dir.y)) (0,0) input)

寻找解决方案

你的类型有问题。那么让我们看看一些类型:
foldp : (a -> b -> b) -> b -> Signal a -> Signal b
input : Signal (Float, {x : Int, y : Int})
render : (Int, Int) -> Element
main : Signal Element

main的定义范围内问题似乎源于 foldp ,所以让我们制作 foldp 的类型在 main 的上下文中更具体. render映射到输出,所以 b应该是 (Int, Int) ,对应于 (0,0)初始值。 a应该像输入。所以对于具体的 foldp主要有:
foldp :  ((Float, {x : Int, y : Int}) -> (Int, Int) -> (Int, Int)) -- the function
-> (Int, Int) -- the initial value
-> Signal (Float, {x : Int, y : Int}) -- the input
-> Signal (Int, Int) -- the output

好的,所以我们知道 foldp 的函数参数是什么类型的应该有。但是当前函数有什么错误类型?
(\dir (upd, {x, y}) -> (x + dir.x, y + dir.y)) : {recordExt1 | x : number, y : number'} -> (something, {recordExt2 | x : number, y : number'}) -> (number, number')

嗯.. 看起来太复杂了。让我们用一些假设来简化。
* 我们可能不需要扩展记录,所以使用 recordExt1 = recordExt2 = {} .
* 两人 number s 很可能 Int s。
* something 是元组中的第一个,记录为 xy ,所以必须是 Float来自 input信号。
-- simplified type of inline function
{ x : Int, y : Int} -> (Float, { x : Int, y : Int}) -> (Int, Int)
-- function deduced from specialised `foldp` type
(Float, {x : Int, y : Int}) -> (Int, Int) -> (Int, Int)

那些看起来很像。函数的第一个和第二个参数交换,第二个参数应该是整数元组而不是整数记录 xy .

回顾

你可以看看 main的其他定义是如何的在评论中是有效的,但随后您更改了 (x,y){x,y}并添加了 (upd, ... )围绕错误的论点。

最后一点

如果您实际上不打算使用来自 fps 25 的时间增量,您还可以使用:
input = Signal.sampleOn (fps 25) Keyboard.arrows

main = Signal.map render
(Signal.foldp (\dir (x, y) ->
(x + dir.x, y + dir.y)) (0,0) input)

这给你几乎相同的行为。

关于elm - 使用 foldp 折叠多个信号,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27785162/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com