gpt4 book ai didi

F# 使用可区分联合的基类型

转载 作者:行者123 更新时间:2023-12-03 23:34:26 26 4
gpt4 key购买 nike

我正在学习 F# 并努力尝试使用有区别的联合。我有一个简单的案例,我试图在 Map 类型的简单可区分联合上使用 Map.map 但它说存在类型不匹配。我基本上只是想将价格类型用作 map

这是一个简化的例子:

type Prices = Prices of Map<string, int>

let GetSalePrice (prices: Prices) = prices |> Map.map (fun k v -> (k, v * 2))

给我这个错误:

/Users/luke/code/chronos/Chronos.Mining/Chronos.Mining.Actors/Untitled-1(22,47): error FS0001: Type mismatch. Expecting a
'Prices -> 'a'
but given a
'Map<'b,'c> -> Map<'b,'d>'
The type 'Prices' does not match the type 'Map<'a,'b>'

鉴于我在 map 函数中所做的只是返回值 * 2,我不明白为什么会出现此错误。

最佳答案

您不能“Prices 用作 Map ”,因为 Prices 不是 Map .你定义它的方式,Prices是不同的类型,与 Map 完全不同,但它包含 Map 的一个实例在里面。

如果这确实是你的意思,那么为了得到 MapPrices值,您需要对其进行模式匹配。像这样:

let GetSalePrice (Prices theMap) = theMap |> Map.map ...

哇,这是怎么回事? Prices theMap怎么样不同于 prices: Prices ?为什么我们将类型名称放在参数前面而不是通过冒号放在参数后面? F# 中不就是这样表示类型的吗?

您可能会有些困惑,因为您使用的是同名 Prices对于类型及其构造函数。为了澄清这一点,让我重新定义你的类型:

type PricesType = PricesCtor of Map<string, int>

现在函数看起来像:

let GetSalePrice (PricesCtor theMap) = theMap |> Map.map ...

所以你看,这不是我们放在参数前面的类型。它是构造函数。而这个声明 - (PricesCtor theMap) - 告诉编译器我们需要一个类型为 PricesType 的参数(因为那是 PricesCtor 所属的地方),当我们得到这个参数时,它应该被解包,其中包含的 map 应该命名为 theMap .

这整个过程称为“模式匹配”。在这里,我们匹配构造函数 PricesCtor .


另一方面,您的原始函数仅指定了参数的类型。使用我的新类型定义,我可能会像这样编写您的原始函数:

let GetSalePrice (prices: PricesType) = prices |> Map.map ...

在这里,我们指定参数的类型应为 PricesType , 但随后我们尝试将其用作 Map.map 的参数,它需要一个类型为 Map<_,_> 的参数.难怪会出现类型不匹配!


模式匹配也不必在参数声明中。您可以在代码中的任何位置进行模式匹配。为此,请使用 match关键词。这就是你的函数可以这样写的方式:

let GetSalePrice prices =
match prices with
| PricesCtor theMap -> theMap |> Map.map ...

match一旦你的类型有多个构造函数,关键字就变得很重要。例如:

type PricesType = PricesAsAMap of Map<string, int> | SinglePrice as int

在这种情况下,如果在参数声明中指定模式:

let GetSalePrice (PricesAsAMap theMap) = ...

编译器会警告您模式匹配不完整。确实,您的函数知道在给定 SinglePrice 时该做什么。值,但是当给出 ConstantPrice 时应该怎么办? ?你还没有定义,所以编译器会提示。

此设置是使用 match 的场合。关键词:

let GetSalePrice prices = 
match prices with
| PricesAsAMap theMap -> theMap |> Map.map ...
| SinglePrice p -> "single item", p

关于F# 使用可区分联合的基类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62400128/

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