SML 到 Haskell 的转换
将 SML 代码转换为 Haskell 的一些基本问题。
1)我习惯于在SML代码中使用本地嵌入表达式,例如测试表达式、打印等,它们在加载(评估)代码时进行本地测试和输出。 在 Haskell 中,获得结果(评估)的唯一方法似乎是在模块中添加代码,然后转到另一个模块中的 main 并添加一些内容来调用和打印结果。
这是对的吗?在 GHCi 中,我可以输入表达式并查看结果,但这可以自动化吗? 每次测试评估都必须去顶层 main 对我来说似乎很不方便 - 也许只需要改变我的懒惰范式。
2)在SML中我可以对返回的结果进行模式匹配和统一,例如
val myTag(x) = somefunct(a,b,c);
并在匹配后获取 x 的值。
我可以在 Haskell 中轻松执行类似的操作,而无需编写单独的提取函数吗?
3) 如何使用元组参数(即非柯里化)创建构造函数。
在 SML 中:
数据类型 Thing = Int * Int 的信息;
但在 Haskell 中,我尝试过;
数据事物=信息(Int Int)
失败。 (“Int 应用于类型中的参数太多:一些 Int Int”) 咖喱版本效果很好,
数据事物 = Info Int Int
但我想要非柯里化。
谢谢。
A few basic questions, for converting SML code to Haskell.
1) I am used to having local embedded expressions in SML code, for example test expressions, prints, etc. which functions local tests and output when the code is loaded (evaluated).
In Haskell it seems that the only way to get results (evaluation) is to add code in a module, and then go to main in another module and add something to invoke and print results.
Is this right? in GHCi I can type expressions and see the results, but can this be automated?
Having to go to the top level main for each test evaluation seems inconvenient to me - maybe just need to shift my paradigm for laziness.
2) in SML I can do pattern matching and unification on a returned result, e.g.
val myTag(x) = somefunct(a,b,c);
and get the value of x after a match.
Can I do something similar in Haskell easily, without writing separate extraction functions?
3) How do I do a constructor with a tuple argument, i.e. uncurried.
in SML:
datatype Thing = Info of Int * Int;
but in Haskell, I tried;
data Thing = Info ( Int Int)
which fails. ("Int is applied to too many arguments in the type:A few Int Int")
The curried version works fine,
data Thing = Info Int Int
but I wanted un-curried.
Thanks.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(4)
如果是将调试和跟踪插入到纯代码中,则通常仅在调试时需要。要在 Haskell 中执行此操作,您可以使用
Debug.Trace.trace
、在基础包中。如果您担心调用函数,Haskell 程序会按照依赖顺序从
main
向下进行计算。但是,在 GHCi 中,您可以导入模块并调用您想要的任何顶级函数。如果您愿意,您可以将原始参数返回给函数,方法是将其作为函数结果的一部分,例如使用元组:
<代码>fx = (x, y)
where y = gab c
或者您的意思是返回一个值还是另一个值?然后使用标记联合(求和类型),例如
Either
:使用
(,)
构造函数。例如,虽然更像 Haskell 会是:
并且这些在实践中可能应该是严格的领域:
If it is about inserting debug and tracing into pure code, this is typically only needed for debugging. To do this in Haskell, you can use
Debug.Trace.trace
, in the base package.If you're concerned about calling functions, Haskell programs evaluate from
main
downwards, in dependency order. In GHCi you can, however, import modules and call any top-level function you wish.You can return the original argument to a function, if you wish, by making it part of the function's result, e.g. with a tuple:
f x = (x, y)
where y = g a b c
Or do you mean to return either one value or another? Then using a tagged union (sum-type), such as
Either
:Using the
(,)
constructor. E.g.though more Haskell-like would be:
and those should probably be strict fields in practice:
Debug.Trace
允许您内联打印调试消息。但是,由于这些函数使用unsafePerformIO
,因此与 SML 等按值调用语言相比,它们的行为可能会出现意外的情况。我认为
@
语法正是您在这里寻找的:在 Haskell 中,元组类型用逗号分隔,例如
(t1, t2)
,所以你想要的是:Debug.Trace
allows you to print debug messages inline. However, since these functions useunsafePerformIO
, they might behave in unexpected ways compared to a call-by-value language like SML.I think the
@
syntax is what you're looking for here:In Haskell, tuple types are separated by commas, e.g.,
(t1, t2)
, so what you want is:阅读其他答案,我想我可以提供更多示例和一项建议。
这类似于“let MyTag x = someFunct ab c”示例,但它是模块的顶层。
正如您所注意到的,Haskell 的顶层可以定义命令,但无法仅仅因为您的模块已被另一个模块导入而自动运行任何代码。这与Scheme或SML完全不同。在Scheme中,文件被解释为逐个执行,但Haskell的顶层只是声明。因此,库不能执行正常的操作,例如在加载时运行初始化代码,它们必须提供“pleaseRunMe :: IO ()”类型的命令来执行任何初始化。
正如您所指出的,这意味着运行所有测试需要一些样板代码来列出所有测试。您可以在 hackage 的 测试 组下查看库以获取帮助,例如 test-framework-th。
Reading the other answers, I think I can provide a few more example and one recommendation.
This is like the "let MyTag x = someFunct a b c" examples, but it is a the top level of the module.
As you have noticed, Haskell's top level can defined commands but there is no way to automatically run any code merely because your module has been imported by another module. This is entirely different from Scheme or SML. In Scheme the file is interpreted as being executed form-by-form, but Haskell's top level is only declarations. Thus Libraries cannot do normal things like run initialization code when loaded, they have to provide a "pleaseRunMe :: IO ()" kind of command to do any initialization.
As you point out this means running all the tests requires some boilerplate code to list them all. You can look under hackage's Testing group for libraries to help, such as test-framework-th.
对于#2,是的,Haskell 的模式匹配做了同样的事情。
let
和where
都进行模式匹配。你可以做或者
For #2, yes, Haskell's pattern matching does the same thing. Both
let
andwhere
do pattern matching. You can door