Pergunta

É possível escrever funções com parâmetros de entrada digitadas dinamicamente? Tentei correspondência de padrão, mas aparentemente ele não funciona assim.

Eu gostaria de fazer algo parecido com isto:

fun firstStr (0,n:string) = n
  | firstStr (b:string,n:string) = if b>n then n else b;

Obrigado.

Foi útil?

Solução

StandardML é uma estrita, a linguagem de tipagem estática. Portanto, você não pode ter uma função que aceita um int no primeiro caso e uma corda no segundo. O erro que você recebe é

this clause:        string * string -> 'Z
previous clauses:      int * string -> 'Z
in declaration:
  firstStr =
    (fn (0,<pat> : string) => n
      | (<pat> : string,<pat> : string) => if <exp> > <exp> then n else b)

Se você quer ter um caso que é uma cadeia e um caso que é um int, você pode fazer um novo tipo, um " marcado união "(aka 'união discriminada'), que é projetado para ser fácil de usar com correspondência de padrão. Ele ficaria assim:

datatype Wrapper = Int    of int
                 | String of string
fun firstStr(Int 0,    n:string) = n
  | firstStr(String b, n:string) = if b>n then n else b

Claro, você pode querer encontrar algum nome mais apropriado para este tipo Wrapper, algo que faz sentido no contexto do seu programa. Também vale lembrar que o tipo de anotação em n não é realmente necessário; seria mais idiomática para escrever

fun firstStr(Int 0,    n) = n
  | firstStr(String b, n) = if b>n then n else b

Além disso, o compilador irá dizer-lhe que você deixou um caso ar-livre:? Que se o primeiro argumento é um inteiro não igual a zero

Finalmente, ele não está realmente claro o que você quer dizer com o b>n comparação, o aspecto das duas cordas que você quer comparar? Eu vejo que quando eu comparar duas cordas no SML, vejo uma comparação lexicográfica (aka alfabética). É isso que você queria?

Outras dicas

Para elaborar um pouco, suponha que tem dois argumentos, cada um dos quais poderia ser uma string ou um inteiro, e se você tem duas cordas que você quer a corda lexicographically menor, se você tem uma corda que você quer que corda, e se você tiver dois inteiros você não pode retornar uma string. O que você faz? Retornar um valor do tipo string option (olhar para cima option, SOME e NONE em http: //www.standardml .org / Base / option.html ):

datatype string_or_int = String of string
                       | Int    of int 

fun firstStr(String a, String b) = SOME (if a < b then a else b)
  | firstStr(String a, Int _   ) = SOME a
  | firstStr(Int _,    String b) = SOME b
  | firstStr(Int _,    Int _   ) = NONE

firstStr função tem tipo

string_or_int * string_or_int -> string option

A maneira mais rápida de se tornar um programador ML proficiente é aprender a pensar sobre os tipos de início . Se, por exemplo, o que você realmente queria era uma função do tipo string option * string -> string, você não precisa escrevê-lo sozinho; a função interna getOpt faz isso. Por outro lado, parece que você quer string option * string -> string, assim você pode escrever

fun firstStr(SOME a, b) = if a < b then a else b
  | firstStr(NONE,   b) = b

e você não' precisa de um construtor de valor SOME ou um tipo de option no resultado.

polimórfica variantes em OCaml ter mais de a propriedade dinâmica que você está procurando. Você pode dar uma olhada, se quiser, OCaml e SML são línguas muito próximas.

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