【问题标题】:Types issue in F#F# 中的类型问题
【发布时间】:2023-04-01 12:13:01
【问题描述】:

在我不断深入 f# 的冒险中,我理解了很多这种强大的语言,但有些东西我仍然不太清楚。 我需要掌握的最重要的问题之一是类型。

我正在阅读的这本书非常直截了当,并以直接的方式介绍了实体和主要功能。我可以开始的第一件事是类型。它介绍了列表、选项、元组等主要类型... 很明显,所有这些类型都是 IMMUTABLE 的,原因有很多,原因与函数式编程和函数式编程中的数据一致性有关。嗯,到现在为止都没有问题...

但现在我开始使用具体类型...

嗯...我在管理列表、选项、元组、通过 new 运算符创建的类型和使用 type 关键字创建的具体类型(缩写、具体类型...)等类型时遇到问题。

所以我的问题是:如何有效地对 f# 中的所有类型的数据进行分类/区分????

我可以在 C#、VB.NET 中创建完美的类型分离... 例如,在 VB.NET 中有值和引用类型,而在 C# 中只有引用,并且 int、double 被视为对象(它们是对象,而在 VB.NET 中,值类型不是对象,并且在因此类型)。 那么在 F# 中,我无法在语言的类型之间创建这种差异。 你能帮助我吗?我希望我很清楚。

【问题讨论】:

    标签: .net f# types


    【解决方案1】:

    像 F# 这样的混合函数式/面向对象语言的挑战在于它们必须跨越 函数式 面向对象的概念。尽管这使这些语言非常强大,但也使它们变得庞大;大于严格的函数式语言或严格的 OO 语言。最明显的一个地方是类型目录。

    F# 类型的官方文档是here。如您所见,有不少于 17 种不同的类型...类型。

    但要记住的一点是,任何可以在 F# 中定义或使用的类型都必须可以表示为 .NET 类型(这意味着它也可以被其他 .NET 语言使用)。一个有趣的例子是Discriminated Union 类型(有区别的联合类型类似于枚举,除了每个替代值可以具有与之关联的其他值)。其他 .NET 语言没有可区分的联合类型,因此 F# 编译器将此类类型转换为对象层次结构。但是,在翻译中有些东西会丢失:F# 在编译时“知道”该类型的所有可能情况,但 C# 和 VB.NET 必须假定情况的数量是开放式的。

    【讨论】:

    • "Kind" 通常用于描述类型的“类型”...(嗯,经常在特定上下文中使用,但如果您正在搜索,它会让您足够接近) .
    【解决方案2】:

    您可能误解了 C# 和 VB.NET 中的类型。类型在所有 .NET 语言中的工作方式几乎相同;例如,VB.NET 和 C# 都有值类型和引用类型。

    如果无法从外部更改任何类型,则它可以是不可变的。例如,这两段代码是等价的:

    // an immutable reference type in F#
    type Person =
        {
            FirstName : string
            LastName : string
        }
    
    // an immutable reference type in C#
    public class Person
    {
        public Person(string firstName, string lastName)
        {
            FirstName = firstName;
            LastName = lastName;
        }
    
        public string FirstName { get; private set; }
        public string LastName { get; private set; }
    }
    

    编辑: 除了编译器中的一些特殊语法外,F# 中的内置类型并没有什么特别之处。您可以自己制作 - 以下是 listoption 的示例:

    type List<'a> = Empty
                  | Item of 'a * List<'a>
    
    type Option<'a> = None
                    | Some of 'a
    

    它有助于将 F# 程序集与来自 C# 和 VB.NET 的程序集一起加载到 Reflector;您可以看到编译器根据您的 F# 类型声明生成标准 .NET 类型。

    【讨论】:

      【解决方案3】:

      更新

      为了更好地参考 F# 中的不同类型,请向下滚动到 MSDN article 上的 F# 类型。我发现 MSDN 站点确实有一些关于 F# 的最佳信息。总而言之,您拥有 F# 自己的集合风格(即MapSeq 等)、tuples(它们只是几种类型的类似叉积)、可区分联合等等。

      F# 使用type inference,因此您无需在类型/类中显式指定成员变量的类型。这意味着,在大多数情况下,您不需要指定该变量是 intdouble 或任何与 C# 中类似的引用类型。引用类型和值类型之间的区别基本上是隐藏的。

      另外,当你说:

      VB.NET 有值和引用类型,而在 C# 中只有引用

      这并不完全准确,在 VB.NET/C# 中实际上是相同的,请参阅 Jon Skeet's article 关于引用与值类型以获得非常清晰的解释。

      【讨论】:

      • 我的意思是我知道 C# 或 VB.NET 中有多少种类型,但在 F# 中我还无法弄清楚。我的意思是有可变的,不可变的类型。而且所有来自使用
      • 好吧,关于我所说的 c# 和 vb.net 类型......我很着急,写了一个非常愚蠢的东西......我的意思是在所有 .net 语言中都有参考和值类型,但在 vb.net 中,值类型在 c# 中是它们自己的类型,所有类型都是全局层次结构的一部分......在 c# 中,int 是 Int32 的一个实例,它继承自 Object......虽然这在VB.NET... int、double 等不被 Int32 或其他类包裹,它们是不同的类型,不属于类库
      • @Andry,对不起,但我认为你在 C# 和 VB.NET 方面仍然走错了路。 int 和 Int32 和 Object 之间的关系肯定会令人困惑,但 C# 和 VB.NET 之间的关系完全相同。
      • 好的,好吧...我错了...我很高兴...我可以在一个问题中弄清楚。我一直认为 VB.NET 定义了类库之外的类型......好吧,我相信几年前的一篇文章似乎是错误的......抱歉给您带来的麻烦,并感谢 Pratt 先生提供的信息。 :)
      猜你喜欢
      • 2011-07-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多