首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >哈斯克尔模式匹配的F#版本

哈斯克尔模式匹配的F#版本
EN

Stack Overflow用户
提问于 2012-06-13 21:17:22
回答 3查看 970关注 0票数 9

我如何在F#中干净利落地做这个haskell?

代码语言:javascript
复制
add 1 2 x = 3 + x
add 1 x y = 1 + x + y
add z x y = z + x + y
EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2012-06-13 21:20:32

你不能重载函数本身,但你可以直接使用模式匹配:

代码语言:javascript
复制
let add z x y =               // curried multiple parameters
    match z, x, y with        // convert to three-tuple to match on
    | 1, 2, x -> 3 + x
    | 1, x, y -> 1 + x + y
    | z, x, y -> z + x + y

用法与预期一致:add 1 2 3

如果你愿意使用元组作为参数(也就是放弃currying和部分应用),你甚至可以写得更速记:

代码语言:javascript
复制
let add =                     // expect three-tuple as first (and only) parameter
    function                  // use that one value directly to match on
    | 1, 2, x -> 3 + x
    | 1, x, y -> 1 + x + y
    | z, x, y -> z + x + y

现在的用法是:add (1, 2, 3)

票数 22
EN

Stack Overflow用户

发布于 2012-06-13 21:38:56

回想一下,在Haskell中,general form of functions是一个带有模式的声明列表:

代码语言:javascript
复制
f pat1 ... = e1
f pat2 ... = e2
f pat3 ... = e3

只是case分析的糖而已:

代码语言:javascript
复制
f x1 .. xn = case (x1, .. xn) of
                (pat1, ..., patn) -> e1
                (pat2, ..., patn) -> e2
                (pat3, ..., patn) -> e3

因此,可以使用模式匹配但不使用声明级模式将相同的翻译转换为其他语言。

票数 8
EN

Stack Overflow用户

发布于 2012-06-15 18:48:53

这纯粹是句法上的。Haskell、Standard ML和Mathematica等语言允许您编写不同的匹配用例,就好像它们是不同的函数一样:

代码语言:javascript
复制
factorial 0 = 1
factorial 1 = 1
factorial n = n * factorial(n-1)

而像OCaml和F#这样的语言要求您只有一个函数定义,并在其主体中使用match或等效函数:

代码语言:javascript
复制
let factorial = function
  | 0 -> 1
  | 1 -> 1
  | n -> n * factorial(n-1)

请注意,您不必使用此语法一遍又一遍地复制函数名,并且可以更容易地对匹配大小写进行分解:

代码语言:javascript
复制
let factorial = function
  | 0 | 1 -> 1
  | n -> n * factorial(n-1)

正如雅门所写的,在F#中使用let f a b = match a, b with ...

在经典的红黑树实现中,我发现Standard ML和Haskell中函数名称和右侧的重复相当丑陋:

代码语言:javascript
复制
balance :: RB a -> a -> RB a -> RB a
balance (T R a x b) y (T R c z d) = T R (T B a x b) y (T B c z d)
balance (T R (T R a x b) y c) z d = T R (T B a x b) y (T B c z d)
balance (T R a x (T R b y c)) z d = T R (T B a x b) y (T B c z d)
balance a x (T R b y (T R c z d)) = T R (T B a x b) y (T B c z d)
balance a x (T R (T R b y c) z d) = T R (T B a x b) y (T B c z d)
balance a x b = T B a x b

与等效的OCaml或F#相比:

代码语言:javascript
复制
let balance = function
  | B, z, (T(R, y, T(R, x, a, b), c) | T(R, x, a, T(R, y, b, c))), d
  | B, x, a, (T(R, z, T(R, y, b, c), d) | T(R, y, b, T(R, z, c, d))) ->
      T(R, y, T(B, x, a, b), T(B, z, c, d))
  | a, b, c, d -> T(a, b, c, d)
票数 5
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/11015684

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档