Pergunta

Em "Programação F#", me deparei com uma correspondência de padrões como este (simplifiquei um pouco):

let rec len list = 
  match list with
  | [] -> 0
  | [_] -> 1
  | head :: tail -> 1 + len tail;;

Praticamente, entendo que a última partida reconhece a cabeça e a cauda da lista. Conceitualmente, não entendo por que funciona. Até onde eu entendi :: o operador do consulte, que anexa um valor na posição da cabeça de uma lista, mas não me parece ser usado como operador aqui. Devo entender isso como uma "sintaxe especial" para listas, onde :: é interpretado como um operador ou um "padrão de correspondência", dependendo do contexto? Ou a mesma idéia pode ser estendida para outros tipos que não sejam listas, com outros operadores?

Foi útil?

Solução

Além da resposta de Brian, há alguns pontos que valem a pena notar. o h::t A sintaxe pode ser usada como operador e Como padrão:

let l = 1::2::[]                    // As an operator
match l with x::xs -> 1 | [] -> 0   // As a pattern

Isso significa que é um construto um pouco especial, porque outros operadores (por exemplo +) não pode ser usado como padrões (para decompor o resultado de volta aos argumentos do operador) - obviamente, para +, isso seria ambíguo.

Além disso, o padrão [_] é interessante, porque é um exemplo de padrão aninhado. Ele compõe:

  • _ - Padrão sublinhado, que corresponde a qualquer valor e não liga nenhum símbolo
  • [ <pattern> ] - Padrão de lista de elementos únicos, que corresponde às listas com elementos únicos e corresponde ao elemento da lista com o aninhado <pattern>.

Você também pode escrever match 1::[] with | [x] -> x que retornaria o valor do elemento único (neste caso 1).

Outras dicas

É uma sintaxe especial para listas. Você pode pensar no list digite como uma união discriminada assim:

type list<'T> =         // '
    | Nil
    | Cons of 'T * list<'T>

exceto que há sintaxe especial que faz Nil ser [] e Cons(h,t) ser h::t. Então é apenas um padrão normal correspondente a uma união discriminada. Isso ajuda?

(Possivelmente veja também esta entrada do blog.)

É usado como formatador ou formalmente pattern, `list 'é comparado aos três padrões:

] significa que a lista está vazia

_] significa que a lista tem um elemento, como você não se importa com o que é o elemento, então simplesmente coloque _ lá, você também pode usar [a].

Cabeça :: Tail significa que a lista tem duas partes: uma cabeça e uma cauda.

Você pode visualizar a correspondência de padrões F# como uma estrutura poderosa, caso contrário.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top