我正在为大地测量计算编写一个库.我想要包括的一件事是网格投影的类型(例如军械测量国家网格)和那些网格上的点(由"东方"和"北方"指定).网格由原点指定,该原点将其与地球和一堆几何参数联系起来.应用程序员可以使用这些参数创建许多任意网格.基于不同的基础预测,还将有一系列类型的网格.
显然我希望能够对网格点进行计算(例如距离,方位等),但同时我想使用Haskell类型系统来阻止应用程序员询问不同网格上两点之间的距离.我想知道使用ST monad行的类型参数的Reader Monad是否可以工作,但我希望应用程序员能够将这些位置值存储在monad之外,而ST则是为了防止STRef泄漏runST.
我对底层椭球的大地位置(纬度和经度)也有类似的问题.但是网格版本可能更容易解释,因为这个问题的焦点是类型系统而不是大地测量.
我已经阅读了GADT和存在类型,但我看不出怎么做.
我想用这样的类型创建一个自动机类型:
newtype Auto i o = Auto {runAuto :: i -> (o, Auto i o)}
Run Code Online (Sandbox Code Playgroud)
我知道这是Automata 箭头的类型,但我不是在寻找箭头。我想让它成为一个 monad,所以大概它会有一个类型
newtype Auto i o a = ???? What goes here?
Run Code Online (Sandbox Code Playgroud)
具有这样的功能:
yield :: o -> Auto i o i
Run Code Online (Sandbox Code Playgroud)
因此,当我从 Auto monad 中调用“yield”时,“runAuto”函数返回由“yield”的参数和延续函数组成的对。当应用程序调用延续函数时,参数作为“yield”的结果在 monad 中返回。
我知道这将需要一些延续 monad 的风格,但尽管过去曾与延续争论不休,但我不知道如何编写这个代码。
我也知道这很像 Michael Snoyman 的Conduit monad,除了他将“yield”和“await”分开。这个 monad 必须为每个输入只有一个输出。
背景:我正在编写一些以复杂方式响应 GUI 事件的代码。我希望能够编写接受一系列输入的代码,而不是将其变成手动编码的状态机,以换取随着用户交互的进行而对屏幕进行更新。
编辑
这一切都被证明是微妙的错误。我写了 Petr Pudlák 在他的回复中建议的代码,它似乎有效,但“yield”操作总是产生前一个yield的输出。这很奇怪。
在盯着屏幕看了很久之后,我终于发现我需要把代码贴在这里。关键的区别在于 AutoF 类型。将下面的方法与 Petr 提出的方法进行比较。
import Control.Applicative
import Control.Monad
import Control.Monad.IO.Class
import Control.Monad.State.Class …Run Code Online (Sandbox Code Playgroud) 我正在尝试使用 podman(而不是 Docker)和 Google Cloud Run 迈出我的第一步。我设法构建了一个带有gcr.io标签的图像并将其推送到 Google。然后我创建一个新服务,我可以在“选择图像 URL”弹出对话框中选择图像。但随后该服务无法启动,显示“未找到图像 [全名]”。
我在 Google 的支持页面或其他任何地方都找不到任何内容。我可以拉图像,我可以推送新版本,它们会出现在弹出对话框中。但该服务仍报告无法找到它们。
我究竟做错了什么?
编辑回答以下 DazWilkin 的问题:
你可以使用 Docker 在本地运行 podman 创建的容器吗?
我无法在本地运行 Docker,因为它与 Fedora 31(因此是 podman)不兼容。但我可以使用本地运行它podman run
您可以在 Cloud Run 中部署 Docker 创建的容器吗?
如上:F31。然而,podman 应该是一个替代品。
容器注册表是否与 Cloud Run 在同一个项目中?
是的。我确实遇到了问题,但我收到了一条权限消息,而不是“未找到”。
您是否尝试过通过 gcloud 而不是控制台进行部署?
是的。
$ podman push eu.gcr.io/my-project/hs-hello-world
Getting image source signatures
Copying blob c7f3d2e0289b done
Copying blob def7032cea8e done
Copying config f1c2e2615f done
Writing manifest to image destination
Storing signatures
$ gcloud run deploy …Run Code Online (Sandbox Code Playgroud) 我正在编写Haskell,但这可以应用于任何具有ADT概念的OO或函数语言.我将在Haskell中给出模板,忽略算术运算符已被采用的事实:
class Thing a where
(+) :: a -> a -> a
(-) :: a -> a -> a
x - y = x + negate y
(*) :: (RealFrac b) => a -> b -> a
negate :: a -> a
negate x = x * (-1)
Run Code Online (Sandbox Code Playgroud)
基本上这些是可以加上和减去的东西,也可以乘以实际的小数值.一个例子可能是一个简单的数字列表:加法和减法是成对的(在Haskell中,"(+)= zipWith(+)"),乘以实数乘以列表中的每个项目相同的数量.我有足够的其他例子想要将它定义为一个类,但我不知道究竟该怎么称呼它.
在Haskell中,它通常是一个monoid,只要有一些零值.
在代数类型的动物园里,这是一些已知的物体吗?我没有找到戒指,半环,近似,群体等.
在Haskell中,每个运算符都被认为是双参数函数的语法糖(除了一元减号,这是一个词法级异常).
我可以通过将操作符括在括号中将其转换为函数,如下所示:
Prelude> (+) 3 4
7
Run Code Online (Sandbox Code Playgroud)
同样,我可以将一个双参数函数放入一个运算符中,方法是将它包含在后面的标记中:
Prelude> 3 `max` 4
4
Run Code Online (Sandbox Code Playgroud)
那为什么我不能两个都做?
Prelude> (`max`) 3 4
<interactive>:3:7: error: parse error on input ‘)’
Prelude> 3 `(+)` 4
<interactive>:4:4: error: parse error on input ‘(’
Run Code Online (Sandbox Code Playgroud)
第一个是特别令人震惊的,因为以下工作:
Prelude> (`max` 3) 4
4
Run Code Online (Sandbox Code Playgroud) 我有一个haskell函数,看起来像这样:
x 1 = 1 :: Double
x n = ((n-1)/3 + 1/(n-1)) * ((x (n-1))^2) - (n-1)^3/3 + 1 :: Double
Run Code Online (Sandbox Code Playgroud)
不用考虑公式,它应该只加一个,所以x 2 = 2; x 3 = 3,依此类推。但是在Haskell中的结果是:
*Main> x 2
2.0
*Main> x 3
2.9999999999999996
*Main> x 4
3.9999999999999964
*Main>
Run Code Online (Sandbox Code Playgroud)
有人可以告诉我,我需要在第二行中加上什么,以便将数字四舍五入到6个十进制数字吗?我不想解析为int!
谢谢!