Tutorial: Utilizar Visual F# para crear, depurar e implementar una aplicación

En este tutorial se presenta la experiencia de utilizar F# en Visual Studio 2010 junto con .NET Framework 4.

En este tutorial, obtendrá información sobre cómo comenzar a usar Visual Studio 2010 para escribir aplicaciones en F# mediante el ejemplo de un análisis histórico de datos de tasa de interés de la Tesorería de Estados Unidos. Comenzará con un análisis rápido de los datos utilizando la ventana interactiva de F#; después, escribirá y probará código para analizar los datos, y finalmente agregará un front-end de C# para explorar la integración del código de F# con otros lenguajes de .NET.

Requisitos previos

Necesita los componentes siguientes para completar este tutorial:

  • Visual Studio 2010

Nota

Es posible que su equipo muestre nombres o ubicaciones diferentes para algunos de los elementos de la interfaz de usuario de Visual Studio incluidos en las instrucciones siguientes. La edición de Visual Studio que se tenga y la configuración que se utilice determinan estos elementos. Para obtener más información, vea Valores de configuración de Visual Studio.

Para crear un script de F#

  1. Primero, cree un script de F#. En el menú Archivo, elija Nuevo y, a continuación, haga clic en Archivo. En el cuadro de diálogo Nuevo archivo, seleccione Script en la lista Plantillas instaladas y, a continuación, seleccione Archivo de script de F#. Haga clic en Abrir para crear el archivo y, a continuación, guarde el archivo como RateAnalysis.fsx.

  2. Utilice las API de .NET y F# para tener acceso a los datos del sitio de Internet de la Reserva Federal de Estados Unidos. Escriba el código siguiente.

    open System.Net
    open System.IO
    
    let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y10.txt"
    let req = WebRequest.Create(url, Timeout = 10000000)
    let resp = req.GetResponse()
    let stream = resp.GetResponseStream()
    let reader = new StreamReader(stream)
    let csv = reader.ReadToEnd()
    

    Tenga en cuenta lo siguiente:

    • Se colorean las cadenas y palabras clave.

    • Las listas de finalización aparecen después de escribir cada punto (.).

    • Puede tener nombres de método completos y otros identificadores de Visual Studio utilizando el método abreviado de teclado CTRL+ESPACIO o CTRL+J en el medio de un identificador. Una lista de finalización aparece cuando se usa CTRL+J.

    • Cuando se deja el puntero del mouse sobre un identificador en el código, se puede ver una información sobre herramientas que contiene información sobre ese identificador.

    • Si presiona F1 cuando el cursor está en WebRequest, aparece la documentación esperada.

    • Si presiona F1 cuando el cursor está en let, aparece la documentación esperada.

    • De manera predeterminada, se hace referencia a los tipos y espacios de nombres de mscorlib.dll, System.dll y System.Windows.Forms.dll.

    • El valor Timeout que se establece aquí es una propiedad, no un argumento de constructor. F# permite establecer los valores de propiedad de esta manera.

    • Si copia la dirección URL del ejemplo en un explorador, recibirá una lista de valores separados por comas que contienen fechas y tasas de interés, publicada por la Reserva Federal de Estados Unidos.

  3. Ahora ejecutará el código con F# Interactive. Seleccione todo el código (con el mouse o presionando CTRL+A) y haga clic con el botón secundario en Enviar a Interactive. (Asimismo, puede presionar las teclas ALT+ENTRAR).

    • Si aún no esta visible, aparecerá la ventana de F# Interactive.

    • El código se ejecuta correctamente.

    • En la ventana de F# Interactive aparece lo siguiente.

      val url : string =
        "http://www.federalreserve.gov/releases/h15/data/business_day/"+[18 chars]
      val req : System.Net.WebRequest
      val resp : System.Net.WebResponse
      val stream : System.IO.Stream
      val reader : System.IO.StreamReader
      val csv : string =
        "  ,Instrument,"U.S. government securities/Treasury constant m"+[224452 chars]
      
      >
      
  4. A continuación, inspeccione los datos utilizando F# Interactive. En el símbolo del sistema de F# Interactive, escriba csv;; y presione ENTRAR. Escriba csv.Length;; y presione ENTRAR. Tenga en cuenta lo siguiente:

    • Los datos son actuales.

    • F# Interactive muestra el valor de la cadena csv y su longitud, como se muestra aquí.

      07/10/2009, 3.32
      07/13/2009, 3.38
      07/14/2009, 3.50
      07/15/2009, 3.63
      "
      > csv.Length;;
      val it : int = 224513
      
    • La siguiente ilustración muestra la ventana de F# Interactive.

      Ventana de F# Interactive

      Ventana de F# Interactive

  5. Ahora escribirá código de F# para analizar los datos del archivo .csv (valores separados por comas). Así se denomina un archivo CSV porque contiene los valores separado por comas. En el editor de código, agregue el código siguiente. Según agrega cada línea, seleccione el código agregado en esta sección hasta esa línea y presione ALT+ENTER para ver los resultados parciales. Tenga en cuenta lo siguiente:

    • IntelliSense le ofrece información útil después de escribir un punto, incluso en medio de complejas expresiones anidadas.

    • Cuando el código está incompleto (o incorrecto), los subrayado ondulados rojos indican que contiene errores sintácticos y semánticos.

    • Las canalizaciones se crean con al operador de canalización (|>). El operador de canalización toma el valor devuelto de una expresión y lo usa como argumento para la función de la línea siguiente. Las canalizaciones y F# Interactive permiten una ejecución parcial de una línea del código de procesamiento de datos.

    let interest = 
        csv.Split([|'\n'|])
        |> Seq.skip 8
        |> Seq.map (fun line -> line.Trim())
        |> Seq.filter (fun line -> not (line.EndsWith("ND")))
        |> Seq.filter (fun line -> not (line.Length = 0))
        |> Seq.map (fun line -> line.Split([|','|]))
        |> Seq.map ( fun values ->
            System.DateTime.Parse(values.[0]),
            float values.[1])
    
  6. Ahora dará un nombre a esta funcionalidad. Quite 10 de la definición de url y reemplácelo por %d para convertir el literal de cadena en una cadena de formato. Agregue maturity después de la cadena de formato. Seleccione todo el código excepto esta una nueva línea y presione el tabulador. Sobre el bloque de código con sangría, agregue let loadRates maturity =. Al final del bloque de código con sangría, agregue interest. Tenga en cuenta lo siguiente:

    El código tendrá una apariencia similar a la siguiente.

    open System.Net
    open System.IO
    
    let loadRates maturity = 
        let url = sprintf "http://www.federalreserve.gov/releases/h15/data/business_day/H15_TCMNOM_Y%d.txt" maturity
        let req = WebRequest.Create(url, Timeout = 10000000)
        let resp = req.GetResponse()
        let stream = resp.GetResponseStream()
        let reader = new StreamReader(stream)
        let csv = reader.ReadToEnd()
    
        let interest = 
            csv.Split([|'\n'|])
            |> Seq.skip 8
            |> Seq.map (fun line -> line.Trim())
            |> Seq.filter (fun line -> not (line.EndsWith("ND")))
            |> Seq.filter (fun line -> not (line.Length = 0))
            |> Seq.map (fun line -> line.Split([|','|]))
            |> Seq.map ( fun values ->
                System.DateTime.Parse(values.[0]),
                float values.[1])
        interest
    
  7. Ahora utilizará esta funcionalidad en nuevas entradas. Seleccione todo el código y presione ALT+ENTER para ejecutarlo con F# Interactive. En el indicador de F# Interactive, llame a la nueva función loadRates en otras tasas de vencimiento: 1, 2 y 5, en años. Tenga en cuenta lo siguiente:

    • Las definiciones anteriores no se pierden en F# Interactive, pero se dispone de nuevas definiciones.

    • Los datos estructurados complejos se presentan mediante una funcionalidad de impresión especial.

Para desarrollar un componente con F#

  • Cree un proyecto de biblioteca para exponer la funcionalidad que ha creado. En el menú Archivo, elija Nuevo y haga clic en Proyecto. En el cuadro de diálogo Nuevo proyecto, seleccione Visual F# en la lista Plantillas instaladas y, a continuación, en Biblioteca de F# para crear un nuevo proyecto de biblioteca. Asigne al proyecto el nombre RateAnalysis. Copie el código que creó previamente de RateAnalysis.fsx y péguelo en Module1.fs. Cambie la declaración de módulo en Module1.fs de módulo Module1 por módulo RateLoader. En el Explorador de soluciones, cambie el nombre Module1.fs por RateLoader.fs. Tenga en cuenta lo siguiente:

    • La plantilla Biblioteca de F# proporciona un archivo de código con la extensión.fs y un script con la extensión .fsx. Puede utilizar el archivo de script para probar el código de la biblioteca interactivamente.

La siguiente ilustración muestra el cuadro de diálogo Nuevo proyecto con varias opciones disponibles para F#. La plantilla Biblioteca de F# está seleccionada.

Opciones de plantilla de F#

Cuadro de diálogo Nuevo proyecto con la biblioteca de F# seleccionada

  1. Ahora creará una clase de F# que expone la funcionalidad deseada. En el Explorador de soluciones, haga clic en el proyecto con el botón secundario, seleccione Agregar y, a continuación haga clic en Nuevo elemento. En el cuadro de diálogo Agregar nuevo elemento, seleccione la categoría Archivo de código fuente de F#. Denomine el archivo Analyzer.fs. Haga clic con el botón secundario en Script.fsx en el Explorador de soluciones y, a continuación, haga clic en Bajar. O bien, presione ALT+FLECHA ABAJO. Pegue el código siguiente en Analyzer.fs.

    module RateAnalysis.Analyzer
    
    open RateLoader
    
    /// Provides analysis of historical interest rate data.
    type Analyzer(ratesAndDates) = 
        let rates = 
            ratesAndDates
            |> Seq.map snd
    
        /// Construct Analyzer objects for each maturity category.
        static member GetAnalyzers(maturities) = 
            maturities
            |> Seq.map loadRates
            |> Seq.map (fun ratesAndDates -> new Analyzer(ratesAndDates))
    
        member sa.Min =
            let date, minRate = (Seq.minBy (fun (_, rate) -> rate) ratesAndDates)
            (minRate, date.ToString("d"))
    
        member sa.Max = 
            let date, maxRate = (Seq.maxBy (fun (_, rate) -> rate) ratesAndDates)
            (maxRate, date.ToString("d"))
    
        member sa.Current =
            rates |> List.ofSeq |> List.rev |> List.head 
    

    Tenga en cuenta lo siguiente:

    • F# admite los conceptos de la programación orientada a objetos. Para obtener más información, vea Clases (F#), Herencia (F#) y otros temas pertinentes en la Referencia del lenguaje F#.
  2. Ahora generará comentarios de documentación XML. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto y, a continuación, seleccione Propiedades. En la pestaña Generar, active la casilla Archivo de documentación XML de la parte inferior de la página. Tenga en cuenta lo siguiente:

    • Puede generar documentación XML para cualquier ensamblado de F#.

    • De forma predeterminada, la documentación XML se genera en la ruta de acceso de salida.

  3. Para compilar el proyecto, presione Ctrl+Mayús+B o F6. Tenga en cuenta lo siguiente:

    • El proyecto se compila correctamente.

    • La ventana Lista de errores no muestra ningún error.

    • El directorio de salida contiene archivos .dll, .pdb y .xml.

    • La Ventana de salida muestra el siguiente resultado:

      ------ Build started: Project: RateAnalysis, Configuration: Debug Any CPU ------
          C:\Program Files (x86)\Microsoft F#\v4.0\fsc.exe -o:obj\Debug\RateAnalysis.exe -g --debug:full --noframework --define:DEBUG --define:TRACE --optimize- --tailcalls- -r:"C:\Program Files (x86)\Microsoft F#\v4.0\FSharp.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\mscorlib.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.Core.dll" -r:"C:\Program Files (x86)\Reference Assemblies\Microsoft\Framework\.NETFramework\v4.0\System.dll" --target:exe --warn:3 --warnaserror:76 --vserrors --utf8output --fullpaths --flaterrors Program.fs RateLoader.fs ValueAnalyzer.fs 
          RateAnalysis -> C:\Users\ghogen\Documents\Visual Studio 10\Projects\RateAnalysis\RateAnalysis\bin\Debug\RateAnalysis.exe
      ========== Build: 1 succeeded or up-to-date, 0 failed, 0 skipped ==========
      
  4. Para agregar una aplicación cliente de C#, haga clic con el botón secundario en el nodo de la solución, elija Agregar y, a continuación, haga clic en Nuevo proyecto. En el cuadro de diálogo Agregar nuevo proyecto, seleccione Visual C# en la lista Plantillas instaladas y, a continuación, seleccione Aplicación de consola. Puede tener que expandir el nodo Otros lenguajes. Denomine el proyecto CSharpDriver. Haga clic con el botón secundario en el nodo Referencias de este proyecto y, a continuación, haga clic en Agregar referencia. En la pestaña Proyectos del cuadro de diálogo Agregar referencia, seleccione RateAnalysis y haga clic en Aceptar. Haga clic con el botón secundario en el nodo del proyecto CSharpDriver y, a continuación, haga clic en Establecer como proyecto de inicio. Escriba el siguiente código en el cuerpo del método Main de la aplicación de C#. Tenga en cuenta lo siguiente:

    • Puede agregar referencias proyecto a proyecto a y de C# y F#.

    • Los espacios de nombres y los tipos definidos de F# se pueden utilizar en C# como cualquier otro tipo.

    • Los comentarios de documentación de F# están disponibles en C# IntelliSense.

    • C# tiene acceso a los valores devueltos de tupla de la API de F#. Las tuplas son valores Tuple de .NET Framework 4.

    var maturities = new[] { 1, 2, 5, 10 };
    var analyzers = RateAnalysis.Analyzer.Analyzer.GetAnalyzers(maturities);
    
    foreach (var item in analyzers)
    {
        Console.WriteLine("Min = {0}, \t Max = {1}, \t Current = {2}", item.Min, item.Max, item.Current);
    }
    Console.WriteLine("Press Enter to exit.");
    Console.ReadLine();
    
  5. Para depurar la aplicación, presione F11 para compilar la aplicación, inicie la aplicación en el depurador y recorra la primera línea de código ejecutado. Presione F11 varias veces más hasta llegar al código de F# del miembro GetAnalyzers. Tenga en cuenta lo siguiente:

    • Puede pasar con facilidad del código de C# al código de F#.

    • Cada expresión de F# es un paso en el depurador.

    • La ventana Locales muestra los valores de maturities.

    • Si se sigue presionando F11, se evalúa el resto de la aplicación.

    • Los comandos del depurador como Ejecutar hasta el cursor, Establecer instrucción siguiente, Insertar punto de interrupción, Agregar inspección e Ir al desensamblado funcionan como se espera.

Para implementar una aplicación de F#:

  1. En este paso, configurará el proyecto para que tenga como destino una versión diferente de .NET Framework. En el Explorador de soluciones, haga clic con el botón secundario del mouse en el proyecto RateAnalysis de F# y seleccione Propiedades. En la pestaña Aplicación, cambie el valor de Versión de .NET Framework de destino por .NET Framework 3.5. Tenga en cuenta lo siguiente:

    • F# permite tener como destino versiones diferentes de .NET Framework.

    • Cuando se cambia la versión de .NET Framework de destino, es preciso recargar el proyecto.

    • Después de cambiar la versión de .NET Framework de destino, algunas referencias de ensamblado no están habilitadas en el cuadro de diálogo Agregar referencia y no están disponibles.

  2. En el proyecto de C#, debe agregar una referencia a la versión del ensamblado de FSharp.Core que tiene como destino .NET Framework 2.0, que también se debe utilizar cuando se tiene como destino las versiones 3.0 y 3.5 de .NET Framework. Haga clic con el botón secundario en el nodo Referencias en el Explorador de soluciones y, a continuación, haga clic en Agregar referencia. En la pestaña .NET, seleccione FSharp.Core version 2.0.0.0 y haga clic en Aceptar. Vuelva a generar la solución.

  3. Para establecer los requisitos previos, haga doble clic en el nodo Propiedades en CSharpDriver. En la pestaña Publicar, haga clic en el botón Requisitos previos y, en el cuadro de diálogo Requisitos previos, active la casilla Runtime de Microsoft Visual F# para .NET 2.0. Tenga en cuenta lo siguiente:

    • F# tiene un paquete de runtime que es independiente de .NET Framework.

    • Este paquete de runtime debe agregarse explícitamente como requisito previo al implementar aplicaciones que usen F#.

    • Hay dos paquetes de runtime disponibles: la versión 2.0 para las versiones 2.0, 3.0 y 3.5 de .NET Framework, y la versión 4 para .NET Framework 4.

  4. Implemente la aplicación C# utilizando ClickOnce. Haga clic con el botón secundario en el proyecto CSharpDriver y haga clic en Publicar. En el Asistente para publicación, haga clic en Finalizar. Ejecute la aplicación CSharpDriver resultante. Tenga en cuenta lo siguiente:

    • El paquete de runtime de visual F# se incluye con la aplicación.

    • Al ejecutar la aplicación, se instala el paquete de runtime de F# y la aplicación se ejecuta correctamente.

Pasos siguientes

Aprenda los conceptos básicos de la escritura de código de F# en Tutorial: Implementar el primer programa en F#; encuentre información sobre las funciones de F# en Funciones como valores de primera clase (F#). Puede explorar el lenguaje F# leyendo Referencia del lenguaje F#.

Vea también

Otros recursos

Tutoriales de Visual F#

Ejemplos y tutoriales (F#)