То, против чего возражает компилятор, является выражением cs.Head
, поскольку из этого выражения он не может определить тип cs
. Это может быть список Card
s, но это также может быть любой другой класс с Head
членом: в этот момент в коде , F # не может сказать, что такое cs
. (Позже, когда вы делаете for i in cs do ... card_color i
, этого будет достаточно для определения типа cs
, но компилятор F # является однопроходным компилятором, поэтому, когда он встречает cs.Head
, у него еще нет никаких других подсказок типа о тип cs
.)
Определите тип cs
в определении вашей функции следующим образом:
let all_same_color (cs : Card list) =
// ...
и этого будет достаточно. Или вы также можете заменить cs.Head
на List.head cs
, и этого будет также , чтобы компилятор F # определил тип cs
:
let col = card_color (List.head cs)
И вы заметите, что теперь нет необходимости указывать, что List.head cs
является Card
, или что col
является Color
, потому что сигнатура функции card_color
позволяет F # вычислять все это из.
Кстати, есть еще более простой способ определить, все ли в вашем списке карт одного цвета, используя List.map
и List.distinct
:
let allSameColor cs =
let distinctColors = cs |> List.map card_color |> List.distinct
List.length distinctColors = 1
Две строки (которые могли бы даже быть одной строкой достаточно легко, но я подумал, что написать это в две строки сделает это проще), которые делают то же самое, что и ваша оригинальная функция all_same_color
(и обратите внимание, что я использовал camelCase в моем имя функции, потому что camelCase является обычным соглашением для имен функций F #). Единственное отличие состоит в том, что у вашей функции есть побочные эффекты (печать «Black» или «Val: (что-то)»), в то время как я намеренно написал «чистую» функцию без побочных эффектов. Рекомендуется, чтобы каждая функция выполняла только одну вещь: либо возвращают значение или имеют побочный эффект, но не оба.