O que é Hindley-Milner?

encontrei este TermoHindley-Milner , e não tenho a certeza se entendo o que significa.

li os seguintes posts:

mas não há uma única entrada para este termo na Wikipédia onde normalmente me oferece uma concisa explicacao.
Nota - foi agora adicionado

O que é?
Que Línguas e ferramentas implementam ou usam?
Pode dar-me uma resposta concisa?

Author: rethab, 2008-12-30

3 answers

Hindley-Milner é um sistemas do tipo descoberto independentemente por Roger Hindley (que estava olhando para a lógica) e mais tarde por Robin Milner (que estava olhando para linguagens de programação). As vantagens de Hindley-Milner são

  • Ele suporta polimórficos funções; por exemplo, uma função que pode dar-lhe o comprimento da lista independente do tipo de elementos, ou uma função binária, árvore de pesquisa independente do tipo de chaves armazenadas no arvore.

  • Às vezes uma função ou valor pode ter mais de um tipo, como no exemplo da função de comprimento: pode ser "Lista de inteiros para inteiros", "lista de cadeias para inteiros", "lista de pares para inteiros", e assim por diante. Neste caso, uma vantagem de sinal do sistema Hindley-Milner é que cada termo bem tipado tem um único "melhor" tipo , que é chamado de principal tipo . O tipo principal da função list-length é " para qualquer a, function from list of a to integer". Aqui a é um chamado "parâmetro tipo", que é explícito no cálculo lambda Mas implícito na maioria das linguagens de programação. O uso de Parâmetros de tipo explica porque Hindley-Milner é um sistema que implementa parametric polimorfismo . (Se escrever uma definição da função comprimento em ML, pode ver o parâmetro tipo assim:

     fun 'a length []      = 0
       | 'a length (x::xs) = 1 + length xs
    
  • Se um termo tem um tipo Hindley-Milner, então o tipo principal pode ser inferido sem exigir quaisquer declarações de tipo ou outras anotações pelo programador. (Esta é uma bênção mista, como qualquer um pode atestar que já foi manuseado um grande pedaço de código ML sem anotações.)

Hindley-Milner é a base para o sistema de tipo de quase todas as linguagens funcionais estaticamente tipadas. Essas línguas de uso comum incluem Todas estas línguas estenderam Hindley-Milner; Haskell, Clean, and Objective Caml fazê-lo de formas ambiciosas e incomuns. (Extensions are required to deal with mutable variables, since basic Hindley-Milner can be subverted using, for example, a mutable cell holding a list of values of uncome type. Estes problemas são tratados através de uma extensão denominadavalor restrição.)

Muitas outras línguas e ferramentas menores baseadas em linguagens funcionais tipadas usam Hindley-Milner.

Hindley-Milner é uma restrição de Sistema F, que permite mais tipos, mas que requer anotações pelo programador.

 169
Author: Norman Ramsey, 2008-12-30 02:34:42

Você pode ser capaz de encontrar os documentos originais usando Google Scholar ou CiteSeer -- ou sua biblioteca universitária local. O primeiro é velho o suficiente para que você possa ter que encontrar cópias encadernadas do Diário, Eu não poderia encontrá-lo on-line. A ligação que encontrei com a outra foi quebrada, mas pode haver outras. Você certamente será capaz de encontrar papéis que citam estes.

Hindley, Roger J, o esquema principal de tipo de um objecto na lógica combinatória , Operações American Mathematical Society, 1969.

A Theory of Type Polymorphism , Journal of Computer and System Sciences, 1978.
 9
Author: tvanfosson, 2008-12-30 02:12:26

Implementação de inferência do tipo Hindley-Milner em C#:

Inferência do tipo Hindley-Milner sobre (Lisp-ish) s-expressões, em menos de 650 linhas de C#

Note que a implementação está na faixa de apenas 270 linhas de C# (para o algoritmo w propriamente dito e as poucas estruturas de dados para suportá-lo, de qualquer forma).

Excerto de Utilização:

    // ...

    var syntax =
        new SExpressionSyntax().
        Include
        (
            // Not-quite-Lisp-indeed; just tolen from our host, C#, as-is
            SExpressionSyntax.Token("\\/\\/.*", SExpressionSyntax.Commenting),
            SExpressionSyntax.Token("false", (token, match) => false),
            SExpressionSyntax.Token("true", (token, match) => true),
            SExpressionSyntax.Token("null", (token, match) => null),

            // Integers (unsigned)
            SExpressionSyntax.Token("[0-9]+", (token, match) => int.Parse(match)),

            // String literals
            SExpressionSyntax.Token("\\\"(\\\\\\n|\\\\t|\\\\n|\\\\r|\\\\\\\"|[^\\\"])*\\\"", (token, match) => match.Substring(1, match.Length - 2)),

            // For identifiers...
            SExpressionSyntax.Token("[\\$_A-Za-z][\\$_0-9A-Za-z\\-]*", SExpressionSyntax.NewSymbol),

            // ... and such
            SExpressionSyntax.Token("[\\!\\&\\|\\<\\=\\>\\+\\-\\*\\/\\%\\:]+", SExpressionSyntax.NewSymbol)
        );

    var system = TypeSystem.Default;
    var env = new Dictionary<string, IType>();

    // Classic
    var @bool = system.NewType(typeof(bool).Name);
    var @int = system.NewType(typeof(int).Name);
    var @string = system.NewType(typeof(string).Name);

    // Generic list of some `item' type : List<item>
    var ItemType = system.NewGeneric();
    var ListType = system.NewType("List", new[] { ItemType });

    // Populate the top level typing environment (aka, the language's "builtins")
    env[@bool.Id] = @bool;
    env[@int.Id] = @int;
    env[@string.Id] = @string;
    env[ListType.Id] = env["nil"] = ListType;

    //...

    Action<object> analyze =
        (ast) =>
        {
            var nodes = (Node[])visitSExpr(ast);
            foreach (var node in nodes)
            {
                try
                {
                    Console.WriteLine();
                    Console.WriteLine("{0} : {1}", node.Id, system.Infer(env, node));
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex.Message);
                }
            }
            Console.WriteLine();
            Console.WriteLine("... Done.");
        };

    // Parse some S-expr (in string representation)
    var source =
        syntax.
        Parse
        (@"
            (
                let
                (
                    // Type inference ""playground""

                    // Classic..                        
                    ( id ( ( x ) => x ) ) // identity

                    ( o ( ( f g ) => ( ( x ) => ( f ( g x ) ) ) ) ) // composition

                    ( factorial ( ( n ) => ( if ( > n 0 ) ( * n ( factorial ( - n 1 ) ) ) 1 ) ) )

                    // More interesting..
                    ( fmap (
                        ( f l ) =>
                        ( if ( empty l )
                            ( : ( f ( head l ) ) ( fmap f ( tail l ) ) )
                            nil
                        )
                    ) )

                    // your own...
                )
                ( )
            )
        ");

    // Visit the parsed S-expr, turn it into a more friendly AST for H-M
    // (see Node, et al, above) and infer some types from the latter
    analyze(source);

    // ...

... que produz:

id : Function<`u, `u>

o : Function<Function<`z, `aa>, Function<`y, `z>, Function<`y, `aa>>

factorial : Function<Int32, Int32>

fmap : Function<Function<`au, `ax>, List<`au>, List<`ax>>

... Done.

Ver também a implementação JavaScript de Brian McKenna na bitbucket, o que também ajuda a começar (trabalhou para mim).

'HTH,

 6
Author: YSharp, 2016-08-15 23:05:53