Pergunta

Eu tenho tentado entrar em F # e fora por um tempo, mas eu continuo recebendo adiadas. Por quê?

Porque não importa qual recurso 'novatos' Eu tento olhar para eu ver exemplos muito simples que começar a usar o -> operador.

No entanto, em nenhum lugar achei ainda que fornece uma simples explicação clara dos meios que este operador. É como se ele deve ser tão óbvio que ele não precisa de explicação até mesmo para iniciantes completos.

I deve, portanto, ser muito densa ou talvez seja quase 3 décadas de experiência anterior me segurando.

Pode alguém por favor, explicar ou apontar para um recurso verdadeiramente acessível que explica isso?

Foi útil?

Solução

'->' não é um operador. Ele aparece no # sintaxe F em um número de lugares, e seu significado depende de como ele é usado como parte de uma construção maior.

Dentro de um tipo, '->' descreve os tipos de funções como as pessoas têm descrito acima. Por exemplo

let f : int -> int = ...

diz que 'f' é uma função que leva um int e retorna um int.

Dentro de um lambda ( "coisa que começa com 'diversão' palavra-chave"), '->' é a sintaxe que separa os argumentos do corpo. Por exemplo

fun x y -> x + y + 1

é uma expressão que define uma função dois argumentos com a implementação dada.

Dentro de uma construção "match", '->' é a sintaxe que separa os padrões do código que deve ser executado se o padrão é correspondido. Por exemplo, em

match someList with
| [] -> 0
| h::t -> 1

o material para a esquerda de cada '->'. São padrões, e as coisas à direita é o que acontece se o padrão da esquerda foi combinado

A dificuldade de entendimento pode ser enraizada na suposição equivocada de que '->' é "um operador" com um único significado. Uma analogia pode ser "" em C #, se você nunca viu qualquer código antes, e tentar analisar o "" operador a partir do olhar "obj.Method" e "3,14" e "System.Collections", você pode ficar muito confuso, porque o símbolo tem significados diferentes em contextos diferentes. Depois de saber o suficiente da língua para reconhecer esses contextos, no entanto, as coisas tornam-se claras.

Outras dicas

Basicamente, significa "mapeia para". Leia-lo dessa forma ou como "se transforma em" ou algo parecido.

Assim, a partir do F # em 20 minutos tutorial,

> List.map (fun x -> x % 2 = 0) [1 .. 10];;
val it : bool list
= [false; true; false; true; false; true; false; true; false; true]

O código (diversão i -> i% 2 = 0) define uma função anônima, chamado de lambda expressão, que tem um parâmetro x e a função retorna o resultado de "x % 2 = 0" , que é ou não é x mesmo.

A primeira pergunta - você está familiarizado com expressões lambda em C #? Se assim o -> em F # é o mesmo que o => em C # (eu acho que você lê-lo 'vai para')

.

O operador -> também podem ser encontradas no contexto de correspondência de padrões

match x with
| 1 -> dosomething
| _ -> dosomethingelse

Eu não tenho certeza se esta é também uma expressão lambda, ou outra coisa, mas acho que o 'vai para' ainda se mantém.

Talvez o que você está realmente se referindo é 'respostas enigmáticas' o # do analisador F:

> let add a b = a + b
val add: int -> int -> int

Isto significa (como a maioria dos exemplos explicar) que add é um 'val' que leva dois inteiros e retorna um int. Para mim, este foi totalmente opaco para começar. Quer dizer, como eu sei que add não é um val que leva um int e retorna dois ints?

Bem, a coisa é que, em certo sentido, ele faz. Se eu lhe adicionar apenas um int, eu voltar um (int -> int):

> let inc = add 1
val inc: int -> int

Este (currying) é uma das coisas que faz F # tão sexy, para mim.

Para informações úteis sobre F #, eu descobri que os blogs são muito mais útil que qualquer um dos 'documentos' oficial: Aqui estão alguns nomes para check-out

(a -> b) "a função de um para b" meios. Em tipo de anotação, denota um tipo de função. Por exemplo, f: (int -> String) meios que f refere-se a uma função que leva um número inteiro e retorna uma cadeia de caracteres. É também usado como um contstructor de tais valores, que na

val f : (int -> int) = fun n -> n * 2

o que cria um valor que é uma função de um número n para que mesmo número multiplicado por dois.

Há uma abundância de grandes respostas aqui já, eu só quero acrescentar à conversa uma outra maneira de pensar sobre isso.

'->' significa função.

'a ->' b é uma função que recebe um 'a e retorna um' b

( 'a * 'b) -> (' c * 'd) é uma função que recebe o tuplo de tipo (' a, 'b), e retorna um tuplo de (' c,' d). Tais como int / String Retorna flutuar / char.

Onde fica interessante é no caso cascata de 'a ->' b -> 'c. Esta é uma função que recebe um 'a e retorna uma função (' b -> 'c), ou uma função que recebe um' b -.> C

Então, se você escrever: seja f X Y Z = ()

O tipo será f: 'a ->' b -> 'c -> unidade, por isso, se você só aplicou o primeiro parâmetro, o resultado seria uma função curry' b -> 'c ->' unidade.

A partir Microsoft :

tipos de função são os tipos de dado de primeira classe e os valores da função são int escrita -> int. Eles são iguais aos tipos de delegado .NET, a não ser que Não são dados nomes. Todas as funções F # identificadores pode ser usado como primeira classe os valores da função, e anônimo Os valores de função podem ser criadas usando o (diversão ... -> ...). forma de expressão

Muitos grandes respostas para estas questões, graças pessoas. Eu gostaria de colocar aqui uma resposta editável que traz coisas juntos.

Para aqueles familiarizados com C # entendimento -> sendo o mesmo que => expressão lamba é um bom primeiro passo. Esse uso é: -

fun x y -> x + y + 1

Pode ser entendido como o equivalente a: -

(x, y) => x + y + 1;

No entanto fica claro que -> tem um significado mais fundemental que decorre desde o conceito de que uma função que recebe dois parâmetros, tais como o acima pode ser reduzido (que é o termo correto?) Para uma série de funções tendo apenas um parâmetro.

Assim, quando o anterior é descrito em como isto: -

Int -> Int -> Int

É realmente ajudou a saber que -> é associativa direito daí o acima podem ser considerados: -

Int -> (Int -> Int)

Aha! Nós temos uma função que leva Int e volta (Int -> Int). (? Uma função curry)

A explicação que -> também pode aparecer como parte do tipo definiton também ajudou. (Int -> Int) é do tipo de qualquer de função que leva uma Int e retorna um int

.

Também útil é o -> aparece em outra sintaxe, como correspondência, mas não ele não tem o mesmo significado? Isso está correto? Eu não tenho certeza que é. Eu suspeito que ele tem o mesmo significado, mas eu não tenho o vocabulário para expressar isso ainda.

Observe o propósito de esta resposta não é para desovar mais respostas, mas para ser editado colaborativamente por vocês para criar uma resposta mais definitiva. Utlimately seria bom que todas as uncertainies e Fluf (tal como neste parágrafo) ser removido e melhores exemplos adicionado. Vamos tentar manter esta resposta o mais acessível para os não iniciados possível.

No contexto da definição de uma função, que é semelhante ao => da expressão lambda em C # 3.0.

F#: let f = fun x -> x*x
C#: Func<int, int> f = x => x * x;

O -> em F # também é usado na correspondência de padrões, onde ela significa: se a expressão corresponde a parte entre | e ->, então o que vem depois -> deve ser devolvido como o resultado:

let isOne x = match x with
 | 1 -> true
 | _ -> false

A coisa agradável sobre linguagens como Haskell (que é muito semelhante em F #, mas eu não sei a sintaxe exata - isto deve ajudar a compreender ->, embora) é que você pode aplicar apenas partes do argumento, para criar curry funções:

adder n x y = n + x + y

Em outras palavras: "dá-me três coisas, e eu vou adicioná-los juntos". Quando você joga os números para ele, o compilador irá inferir os tipos de n x e y. Digamos que você escrever

adder 1 2 3

O tipo de 1, 2 e 3 é Int. Portanto:

adder :: Int -> Int -> Int -> Int

Isto é, dá-me três inteiros, e eu me tornarei um inteiro, finalmente, ou a mesma coisa que dizer:

five :: Int
five = 5

Mas, aqui está a parte boa! Tente isto:

add5 = adder 5

Como você se lembra, víbora leva um int, um int, um int, e lhe dá de volta um int. No entanto, isso não é toda a verdade, como você verá em breve. Na verdade, add5 terá este tipo:

add5 :: Int -> Int -> Int

Será como se você tiver "arrancado" dos inteiros (mais à esquerda), e colou-lo diretamente para a função. Olhando mais de perto a assinatura da função, notamos que a -> são associativa à direita, ou seja:

.
addder :: Int -> (Int -> (Int -> Int))

Isso deve deixar bem claro: Quando você dá víbora o primeiro inteiro, vai avaliar a tudo o que está à direita da primeira seta, ou:

add5andtwomore :: Int -> (Int -> Int)
add5andtwomore = adder 5

Agora você pode usar add5andtwomore em vez de "víbora 5". Dessa forma, você pode aplicar outro inteiro para chegar (digamos) "add5and7andonemore":

add5and7andonemore :: Int -> Int
add5and7andonemore = adder 5 7

Como você vê, add5and7andonemore quer exatamente outro argumento, e quando você dá a ele um, de repente se tornará um inteiro!

  > add5and7andonemore 9
 => ((add5andtwomore) 7) 9
 => ((adder 5) 7) 9)
<=> adder 5 7 9

Substituindo os parâmetros para adder (n x y) para (5 7 9), obtemos:

  > adder 5 7 9 = 5 + 7 + 9
 => 5 + 7 + 9
 => 21

Na verdade , mais também é apenas uma função que leva um int e lhe dá de volta outra int, assim que o acima é realmente mais como:

  > 5 + 7 + 9
 => (+ 5 (+ 7 9))
 => (+ 5 16)
 => 21

Não que você vá!

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