F#Seq.head& Seq.tail类型与自定义类型不匹配 [英] F# Seq.head & Seq.tail type mismatch with custom types
问题描述
type Suit = Spades | Clubs | Hearts | Diamonds
type Rank = Ace | Two | Three | Four | Five | Six | Seven | Eight | Nine | Ten | Jack | Queen | King
type Card = {suit: Suit; rank: Rank}
type Hand = Card seq
let AllSuits = [ Spades; Clubs; Hearts; Diamonds ]
let AllRanks = [ Ace; Two; Three; Four; Five; Six; Seven; Eight; Nine; Ten; Jack; Queen; King ]
let cardValue (card:Card) =
match card.rank with
| Ace -> 1
| Two -> 2
| Three -> 3
| Four -> 4
| Five -> 5
| Six -> 6
| Seven -> 7
| Eight -> 8
| Nine -> 9
| Ten | Jack | Queen | King -> 10
let rec handValue (hand:Hand) =
if Seq.length hand = 1
then cardValue Seq.head
else cardValue Seq.head + handValue Seq.tail
我有自定义类型Rank
和Suit
,它们组合成一个自定义类型Card
和一个自定义类型集合Hand
,它是一系列卡片.
I have custom types Rank
, and Suit
, combined into a custom type Card
, and a custom type collection Hand
which is a sequence of cards.
当我在递归handValue
函数中使用Seq.head
时,出现错误:
When I use Seq.head
in the recursive handValue
function I get the error:
该表达式应具有类型'Card'
,但此处具有类型''a -> 'b'
This expression was expected to have type 'Card'
but here has type ''a -> 'b'
我的印象是,由于hand
是Card
的序列,因此Seq.head
将返回序列中的第一个元素,类型为Card
.
I was under the impression that as the hand
is a sequence of Card
, that Seq.head
would return the first element in the sequence, as type Card
.
当我使用Seq.tail
时,我也会收到错误消息:
Also when I use Seq.tail
I get the error:
''a -> seq<'b>'
类型与'Hand'
The type ''a -> seq<'b>'
is not compatible with the type 'Hand'
我的印象是Seq.tail
将返回Card
的序列,尽管未明确声明为Hand
,但在功能上应该相同.
I was under the impression that Seq.tail
would return a sequence of Card
, which although not explicitly declared as a Hand
should be identical in functionality.
我不确定如何处理第一个错误,对于第二个错误,最合适的方法是什么?将Hand
类型转换为Sequence
类型,并使用Seq.tail
,将返回的Sequence
类型转换为Hand
类型.
I'm unsure how to approach the first error at all, and for the second error what would be the most appropriate; casting the Hand
type to a Sequence
type and using Seq.tail
, casting the returned Sequence
type as a Hand
type.
或者我完全忽略了语法中的一些小问题.任何帮助将不胜感激.
Or perhaps there is something minor in the syntax that i'm overlooking completely. Any help would be greatly appreciated.
推荐答案
您正在传递cardValue
Seq.head
函数;您需要先应用该函数,然后传递结果:
You're passing cardValue
the Seq.head
function; you need to apply that function first and pass the result instead:
let rec handValue (hand:Hand) =
if Seq.length hand = 1
then cardValue (Seq.head hand)
else cardValue (Seq.head hand) + handValue (Seq.tail hand)
如果传递空序列并且不是尾递归,则将失败;修复这些问题,并去除一些多余的内容,可以得到类似的结果:
N.b. this will fail if passed an empty sequence and isn't tail recursive; fixing these, along with a little redundancy removal, yields something like:
let handValue hand =
let rec impl acc h =
if Seq.isEmpty h then acc
else impl (cardValue (Seq.head h) + acc) (Seq.tail h)
impl 0 hand
也就是说,这是极端的低效率;使用list
而不是seq
时,此代码结构会很好用,但是使用高阶函数处理后者要好得多 :
That said, this is extremely inefficient; this code structure would work fine when using a list
rather than a seq
, but you're much better off using higher-order functions to process the latter:
let handValue hand = hand |> Seq.sumBy cardValue
这篇关于F#Seq.head& Seq.tail类型与自定义类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!