SML 到 Haskell 的转换

发布于 2024-10-31 09:51:11 字数 790 浏览 2 评论 0原文

将 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(4

顾忌 2024-11-07 09:51:11
  • 这个问题有点不清楚——你是问如何评估 Haskell 中的函数?

如果是将调试和跟踪插入到纯代码中,则通常仅在调试时需要。要在 Haskell 中执行此操作,您可以使用 Debug.Trace.trace在基础包中。

如果您担心调用函数,Haskell 程序会按照依赖顺序从 main 向下进行计算。但是,在 GHCi 中,您可以导入模块并调用您想要的任何顶级函数。

  • 如果您愿意,您可以将原始参数返回给函数,方法是将其作为函数结果的一部分,例如使用元组:

    <代码>fx = (x, y)
    where y = gab c

或者您的意思是返回一个值还是另一个值?然后使用标记联合(求和类型),例如 Either

f x = if x > 0 then Left x
                else Right (g a b c)
  • How do I do a constructor with a tuple argument, ie uncurried in SML

使用 (,) 构造函数。例如

 data T = T (Int, Int)

,虽然更像 Haskell 会是:

 data T = T Int Bool

并且这些在实践中可能应该是严格的领域:

 data T = T !Int !Bool
  • This question is a bit unclear -- you're asking how to evaluate functions in 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:

f x = if x > 0 then Left x
                else Right (g a b c)
  • How do I do a constructor with a tuple argument, i.e. uncurried in SML

Using the (,) constructor. E.g.

 data T = T (Int, Int)

though more Haskell-like would be:

 data T = T Int Bool

and those should probably be strict fields in practice:

 data T = T !Int !Bool
芸娘子的小脾气 2024-11-07 09:51:11
  1. Debug.Trace 允许您内联打印调试消息。但是,由于这些函数使用 unsafePerformIO,因此与 SML 等按值调用语言相比,它们的行为可能会出现意外的情况。

  2. 我认为 @ 语法正是您在这里寻找的:

    data MyTag = MyTag Int Bool 字符串
    
    someFunct::MyTag -> (MyTag、整数、布尔值、字符串)
    someFunct x@(MyTag abc) = (x, a, b, c) -- x 绑定到整个参数
    
  3. 在 Haskell 中,元组类型用逗号分隔,例如 (t1, t2),所以你想要的是:

    数据事物 = Info (Int, Int)
    
  1. Debug.Trace allows you to print debug messages inline. However, since these functions use unsafePerformIO, they might behave in unexpected ways compared to a call-by-value language like SML.

  2. I think the @ syntax is what you're looking for here:

    data MyTag = MyTag Int Bool String
    
    someFunct :: MyTag -> (MyTag, Int, Bool, String)
    someFunct x@(MyTag a b c) = (x, a, b, c) -- x is bound to the entire argument
    
  3. In Haskell, tuple types are separated by commas, e.g., (t1, t2), so what you want is:

    data Thing = Info (Int, Int)
    
何止钟意 2024-11-07 09:51:11

阅读其他答案,我想我可以提供更多示例和一项建议。

data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]

someFunct :: Char -> Char -> Char -> ThreeConstructors

MyTag x = someFunct 'a' 'b' 'c'

这类似于“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.

data ThreeConstructors = MyTag Int | YourTag (String,Double) | HerTag [Bool]

someFunct :: Char -> Char -> Char -> ThreeConstructors

MyTag x = someFunct 'a' 'b' 'c'

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.

海风掠过北极光 2024-11-07 09:51:11

对于#2,是的,Haskell 的模式匹配做了同样的事情。 letwhere 都进行模式匹配。你可以做

let MyTag x = someFunct a b c
in ...

或者

...
where MyTag x = someFunct a b c

For #2, yes, Haskell's pattern matching does the same thing. Both let and where do pattern matching. You can do

let MyTag x = someFunct a b c
in ...

or

...
where MyTag x = someFunct a b c
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文