0votos

Máquina de Turing en el sistema de tipos en F#

por jmgomez hace 3 años

Computación bastante rudimentaria, sólo es capaz de sumar dígitos del 0 al 9 aunque cuantos se quiera. Como se ve en el código debería ser simple ampliarlo para más operaciones aritméticas y para aumentar el número de dígitos (e.g. tratando la computación como una calculadora).

Animado por la elegante solución de @jmgomez al desafío Cálculo número primo con expresiones lambda, propongo realizar algún tipo de computación usando únicamente el sistema de tipos. Lógicamente, la computación debe resolverse en tiempo de compilación, nunca en tiempo de ejecución.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
namespace SolveetJJTP 
 
open System 
open System.Reflection 
open ProviderImplementation.ProvidedTypes 
open Microsoft.FSharp.Core.CompilerServices 
open Microsoft.FSharp.Quotations 
 
[<TypeProvider>] 
type AdditionProvider(config: TypeProviderConfig) as this =  
    inherit TypeProviderForNamespaces() 
 
    let ns = "SolveetJJTP" 
    let asm = Assembly.GetExecutingAssembly() 
 
 
    let rec createTypes (prev:string,last:string)  = 
        match last with 
        | "+" -> let result = Array.sum(prev.ToCharArray() |> Array.map(fun c->c|> string |> Convert.ToInt32)).ToString() 
                 let ty = ProvidedTypeDefinition(result,None) 
                 [ty]         
        | _   -> let next = prev+last 
                 ["0";"1";"2";"3";"4";"5";"6";"7";"8";"9";"+"] 
                 |> List.map (fun o ->                                                                                          
                              let ty = ProvidedTypeDefinition(o, None)                               
                              ty.AddMembersDelayed(fun ()->createTypes(next,o))                               
                              ty) 
  
    let rootType = ProvidedTypeDefinition(asm, ns, "AdditionTP", None) 
    do rootType.AddMembersDelayed(fun () -> createTypes ("","")) 
     
    do this.AddNamespace(ns, [rootType]) 
                             
[<assembly:TypeProviderAssembly>]  
do() 
1 comentario
0votos

Escrito por jmgomez hace 3 años

Para no perder la costumbre dejo un video mostrando el: intellisense :D

Por otra parte, el proyecto de MS Research
F7 tiene muuuy buena pinta, aunque lo bajé y no logré hacerlo funcionar (puede que sea el mismo que F*...), pero usarlo sería "hacer trampas" ¿no? xD

Por si a alguien le interesa ejecutar el provider, en NuGet hay un paquete que incluye lo necesario para crear nuevos TP. Lo único que habría que hacer para reproducirlo sería, bajar el paquete, incluir más abajo un fichero con el source y con referenciarlo ya estaría listo para ser consumido desde un segundo proyecto.

Comenta la solución

Tienes que identificarte para poder publicar tu comentario.