gpt4 book ai didi

types - 为什么括号在 F# 类型声明中很重要

转载 作者:行者123 更新时间:2023-12-04 15:01:52 40 4
gpt4 key购买 nike

通过在我的 F# 代码中观察这种行为,我完全感到困惑,这里来自一个交互式 session :

Microsoft (R) F# 2.0 Interactive build 4.0.40219.1
Copyright (c) Microsoft Corporation. All Rights Reserved.

For help type #help;;

> type foo = Foo of (string * int);;
type foo = | Foo of (string * int)

> let f = Foo ("bar",42);;
val f : foo = Foo ("bar", 42)

> match f with Foo x -> x;;
val it : string * int = ("bar", 42)

> type bar = Bar of string * int;;
type bar = | Bar of string * int

> let b = Bar ("baz",21);;
val b : bar = Bar ("baz",21)

> match b with Bar x -> x;;
match b with Bar x -> x;;
-------------^^^^^

stdin(7,14): error FS0019: This constructor is applied to 1 argument(s) but expects 2
>

对我来说,使用单个变量在 Foo 和 Bar 上进行模式匹配似乎很明显应该是有效的 - 所以我想知道是否有人知道这种奇怪行为的原因,或者如果你喜欢我认为这是一个错误。

更新:
只是为了澄清,报告的构造函数类型 FooBar是:
> Foo;;
val it : string * int -> foo = <fun:clo@14-1>
> Bar;;
val it : string * int -> bar = <fun:clo@13>

所以当然,他们应该接受相同的有效模式集

最佳答案

我同意这看起来很困惑。正如 pad 解释的那样,这两个声明之间的区别不仅仅是语法上的 - 您实际上是在定义由不同类型组成的可区分联合情况。

  • 如果是 Foo ,案例包含一个 int * string 类型的元素
  • 如果是 Bar ,案例包含两个 int 类型的元素和 string

  • 这两个选项非常相似,但实际上是不同的。如果您查看 the type definitions in the F# specification,您可以看到这一点。 .以下是描述可区分联合的类型定义的位:

    union-type-defn :=
       type-name '=' union-type-cases type-extension-elementsopt

    union-type-cases :=
       '|'opt union-type-case '|' ... '|' union-type-case

    union-type-case :=
       attributesopt   union-type-case-data

    union-type-case-data :=
       ident                                   -- null union case
       ident of type * ... * type      -- n-ary union case



    请注意,“n-ary union case”由多个元素( type * ... * type )组成。一个类型定义如下(毫不奇怪,它可以是一个元组):

    type :=
       ( type )
       type -> type         -- function type
       type * ... * type    -- tuple type
       ...                         -- lots of other types



    我不知道为什么 union-type-case-data 不只使用一元联合大小写(而不是 n-ary)并且总是将元素视为元组。我认为这很有道理,但它可能是 F# 从 OCaml 或 ML 继承的东西。但是,至少规范解释了这一点!

    事实上,我认为规范有点含糊不清,因为你可以对待 Foo of int * int作为 n 元联合案例和带有元组的一元案例(但没有括号类型 ( type ) )。

    关于types - 为什么括号在 F# 类型声明中很重要,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/12088341/

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