F#Seq.head& Seq.tail类型与自定义类型不匹配 [英] F# Seq.head & Seq.tail type mismatch with custom types

查看:113
本文介绍了F#Seq.head& Seq.tail类型与自定义类型不匹配的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

我有自定义类型RankSuit,它们组合成一个自定义类型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'

我的印象是,由于handCard的序列,因此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&amp; Seq.tail类型与自定义类型不匹配的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆