Translate

sábado, 14 de noviembre de 2020

Maybe


Veamos la mónada Maybe, que facilita mucho el uso del tipo Maybe.

Ya conoces la definición del tipo Maybe:

    data Maybe a = Just a | Nothing

Las funciones de Head y Tail de Prelude no son seguras en el sentido de que fallan cuando se llaman en una lista vacía. Podemos definir versiones seguras usando Maybe:


    myHead :: [a] -> Maybe a

    myHead [] = Nothing

    myHead (x:xs) = Just x


    myTail :: [a] -> Maybe []

    myTail [] = Nothing

    myTail (x:xs) = Just xs


Ahora podemos hacer de Maybe una instancia de la clase de tipo Monad, simplemente proporcionando las definiciones apropiadas para return, bind, then y fail:


    import Control.Monad


    instance Monad Maybe where

        return           =   Just

        Nothing  >>= f = Nothing

        (Just x) >>= f = f x

        fail _           =   Nothing


Hay algunas funciones adicionales definidas en la clase de tipo MonadPlus:


    instance MonadPlus Maybe where

        mzero               = Nothing

        Nothing `mplus` x = x

        x `mplus` _         = x


Eso es todo, ¡ahora tenemos una mónada Maybe!

Veamos qué nos da esta mónada:

Un cálculo usando Maybe explícito

    foo :: [a] -> Maybe a

    foo xs =

      case myTail xs of

        Nothing -> Nothing

        Just a -> case myTail a of

                    Nothing -> Nothing

                    Just b -> myHead b

Para combinar cálculos que usan el tipo Maybe, necesitamos expresiones de caso explícitas para hacer coincidir el patrón con el tipo.

Escribamos este cálculo usando la mónada Maybe, primero usando el operador >> =:


    bar :: [a] -> Maybe a

    bar xs =

      myTail xs >>=

        (\a -> myTail a >>=

          (\b -> myHead b))


Ahora cambiemos un poco los saltos de línea y la sangría para que se vea mejor:


    bar2 :: [a] -> Maybe a

    bar2 xs =

      myTail xs >>= (\a ->

      myTail a >>=  (\b ->

      myHead b))


Gracias a la ley de asociatividad, también podemos eliminar los paréntesis innecesarios:


    bar3 :: [a] -> Maybe a

    bar3 xs =

      myTail xs >>= \a ->

      myTail a >>=  \b ->

      myHead b


Esto ya es mucho más limpio, pero finalmente podemos usar la notación do:


    bar3 :: [a] -> Maybe a

    bar3 xs = do

      a <- myTail xs

      b <- myTail a

      myHead b


Claramente, el código monádico final es mucho más legible que el código no monádico original.


Ejemplo: Reducción de barra [5,6]

        bar [5,6]

    -- > substitute [5,6] for xs in definition of bar

        myTail [5,6] >>=

         (\a -> myTail a >>=

          (\b -> myHead b))

    -- > def. myTail

        Just [6]  >>=

         (\a -> myTail a >>=

          (\b -> myHead b))

    -- >  def.2 of (>>=)

         (\a -> myTail a >>=

          (\b -> myHead b))

            [6]

    -- > beta reduction, substitute [6] for a

         myTail [6] >>= (\b -> myHead b)

    -- > reduce myTail

         Just [] >>=  (\b -> myHead b)

    -- >  def.2 of (>>=)   

        (\b -> myHead b) []

    -- > beta reduction, substitute [] for b

       myHead []

    -- > def.1 myHead

      Nothing


Ejemplo: Reducción de barra [5,6,7]

        bar [5,6,7]

    -> sustituir [5,6,7] por xs en la definición de bar

        bar [5,6,7]

    -- > substitute [5,6,7] for xs in definition of bar

        myTail [5,6,7] >>=

         (\a -> myTail a >>=

          (\b -> myHead b))

    -- > def. myTail

        Just [6,7]  >>=

         (\a -> myTail a >>=

          (\b -> myHead b))

    -- >  def.2 of (>>=)

         (\a -> myTail a >>=

          (\b -> myHead b))

            [6,7]

    -- > beta reduction, substitute [6,7] for a

         myTail [6,7] >>= (\b -> myHead b)

    -- > reduce myTail

         Just [7] >>=  (\b -> myHead b)

    -- >  def.2 of (>>=)   

        (\b -> myHead b) [7]

    -- > beta reduction, substitute [7] for b

        myHead [7]

    -- > def myHead

        Just 7

jueves, 12 de noviembre de 2020

Y un día llego .net 5


Charan!

No hablamos mucho de .net por nuestra clara preferencia al software libre pero pero .net 5, viene a taparnos la boca y a afirmar que microsoft, si ama a linux y al open source.

.net 5 es la confluencia de .net con .net core y tiene todas las ventajas de los 2 mundos. .net 5 es independiente de la plataforma, puede correr en Window, Linux y Mac. 

.NET 5 mejora diversos frentes, como en el rendimiento de muchos componentes del framework, los lenguajes C# 9 y F# 5, el rendimiento de algunas bibliotecas para la serialización de JSON y en las opciones de implementación o despliegue, además de haberse expandido el enfoque a Windows para ARM64 y WebAssembly.

 .NET 5 no solo abarca cosas a nivel de servidor, sino también componentes exclusivos de Windows como Windows Forms. En lo que respecta a Linux, se ha incorporado el soporte multiplataforma para ‘System.DirectoryServices.Protocols’, que ya estaba presente en Windows, pero no en Linux y macOS. “‘System.DirectoryServices.Protocols’ es una API de más bajo nivel que ‘System.DirectoryServices’ y habilita (o puede usarse para habilitar) más escenarios. ‘System.DirectoryServices’ incluye conceptos/implementaciones solo para Windows, por lo que no era una elección obvia hacerla multiplataforma. Ambos conjuntos de API permiten controlar e interactuar con un servidor de servicios de directorio, como LDAP o Active Directory.”

Y trae como muchas cosas, seguro que vamos a tener que visitar esta plataforma desde blog. 

Sin más dejo link: 

https://devblogs.microsoft.com/dotnet/announcing-net-5-0/

https://dotnet.microsoft.com/download/dotnet/5.0

https://docs.microsoft.com/es-es/dotnet/core/install/linux


domingo, 8 de noviembre de 2020

¿Qué es una mónada?


Rápidamente nos podemos percatar de la importancia de los acentos! 

Una mónada es una estructura algebraica en la teoría de categorías, y en Haskell se usa para describir cálculos como secuencias de pasos y para manejar efectos secundarios como estado de entrada o salida.

Las mónadas son abstractas y tienen muchos ejemplos concretos útiles.

Las mónadas proporcionan una forma de estructurar un programa.

Se pueden usar (junto con tipos de datos abstractos) para permitir que las acciones (por ejemplo, variables mutables) se implementen de forma segura.

Una mónada tiene tres bloques de construcción:

  • Un constructor de tipos que produce el tipo de cálculo, dado el tipo de resultado de ese cálculo.
  • Una función que toma un valor y devuelve un cálculo que, cuando se ejecuta, producirá ese valor.
  • Una función que toma dos cálculos y los realiza uno tras otro, haciendo que el resultado del primer cálculo esté disponible para el segundo.

Una mónada consta de tres objetos, que deben satisfacer las leyes de la mónada. Veamos primero los objetos:

Un constructor de tipo M, tal que para cualquier tipo a, el tipo M a es el tipo de cálculo en la mónada M que produce un resultado de tipo a.

Una función return :: a → M a. Por lo tanto, si x :: a, return x es un cálculo en M que, cuando se ejecuta, producirá un valor de tipo a.

Una función (>> =) :: M a → (a → M b) → M b.

El primer argumento es un cálculo que produce un valor de tipo a.

El segundo argumento es una función que requiere un argumento de tipo a y devuelve un cálculo que produce un valor de tipo b.

Las leyes de las mónadas es un cálculo que producirá un valor de tipo b. Funciona ejecutando el primer cálculo y pasando su resultado a la función que devuelve el segundo cálculo, que luego se ejecuta.

Las mónadas son abstractas, generales y útiles.

En consecuencia, hay muchos casos de ellos.

Esto se captura mediante la definición de una clase de tipo para las mónadas, junto con muchas instancias estándar.

    class Monad m where

        return :: a -> m a

        (>>=) :: m a -> (a -> m b) -> m b

        (>>)   :: m a -> m b -> m b

        fail   :: String -> m a


La función de retorno toma un valor y devuelve un valor monádico, es decir, un valor envuelto en el constructor de tipo monada.

El operador >> = (pronunciado "bind") es una parte crucial de una mónada. Vincula un valor devuelto de un cálculo a otro cálculo.

El operador >> (pronunciado "then") es como >> =, pero simplemente ignora el valor devuelto por el cálculo:

    m >> n = m >> = \ _ -> n

El sistema utiliza la función de error para ayudar a producir mensajes de error cuando hay un patrón que no coincide; normalmente no lo usa directamente.

Cada mónada debe satisfacer las siguientes tres leyes. Entonces, si algo parece una mónada pero no satisface estas leyes, ¡no es una mónada! Las leyes expresan propiedades que deben satisfacerse para hacer componibles los cálculos monádicos.

La ley de unidad correcta:

    m >> = retorno = m

La ley de la unidad izquierda:

    devuelve x >> = f = f x

La ley de asociatividad:

    (m >> = f) >> = g = m >> = (\ x -> f x >> = g)

Hay muchas metáforas o intuiciones sobre lo que es una mónada.

Ejemplo: un "cálculo" o una "acción". Pero estos términos son vagos: pueden ayudarlo a comprender, pero a veces también pueden ser engañosos.

Una mónada es exactamente lo que dice la definición, ni más ni menos.

Escribir cálculos monádicos usando los operadores bind y then sigue siendo algo torpe. Haskell proporciona un azúcar sintáctico muy conveniente para cálculos monádicos llamado "notación do":

    baz :: [a] -> Maybe a

    baz xs =

      do  a <- myTail xs

          b <- myTail a

          c <- myHead b

          return c


Reglas de sintaxis para hacer

    do { x }  -- >  x

    do {x ; <xs> }  -- >  x >> do { <xs> }

    do { a <- x ; <xs> }  -- >  x >>= \a -> do { <xs> }

    do { let <declarations> ; xs }    -- >   let <declarations> in do { xs }

sábado, 7 de noviembre de 2020

En un lenguaje funcional, solo hay funciones

Aunque parezca que un lenguaje como Haskell tiene muchos objetos y construcciones diferentes, podemos expresarlos todos en términos de funciones. 

  let

      n = 10

      f x = x+1

    in

      f n


-- Una variable por let =>


    let

      n = 10

    in

      let  

        f x = x+1

      in

        f n


-- Reescribe f como lambda  =>

        

    let

      n = 10

    in

      let  

        f = \x -> x+1

      in

        f n


-- Reescribe el let interno como lambda =>


    let

      n = 10

    in

      (\f -> f n) (\x -> x+1)  


-- Reescribe el let externo como lambda =>


    ( \n -> ((\f -> f n) ( \x -> x+1 )) ) 10    


Entonces, las variables y las expresiones let son solo azúcar sintáctico para las expresiones lambda.

    tp = (1,"2",[3])

La notación de tupla es azúcar sintáctica para una aplicación de función:

    tp = mkTup 1 "2" [3]

La función de construcción de tuplas se puede definir de nuevo simplemente usando lambdas:

   mkTup = \x y z -> \t -> t x y z

Lo mismo ocurre con las funciones de acceso a la tupla:

    fst tp = tp (\x y z -> x)

    snd tp = tp (\x y z -> y)

Las listas se pueden definir en términos de listas vacías [] y la operación de contras (:).

    ls = [1,2,3]

Se puede escribir con : y [] =>

    ls = 1 : 2 : 3 : []

O usando cons =>

 ls = cons 1 (cons 2 (cons 3 []))

Podemos definir cons usando solo funciones lambda como

  cons = \x xs ->

   \c -> c x xs

Así

    ls = cons 1 (...)

       = \c -> c 1 (...)

También podemos definir head y tail usando solo lambdas:

    head ls = ls (\x y -> x)

    tail ls = ls (\x y -> y)

 

Podemos definir la lista vacía de la siguiente manera:

 [] = \f -> true

Las definiciones de verdadero y falso se dan a continuación bajo Booleanos.

Luego podemos verificar si una lista está vacía o no:

    isEmpty lst = lst (\x xs -> false)

Una lista no vacía siempre se define como: 

lst = x: xs

que con nuestra definición de (:) es

    lst = (\x xs -> \c -> c x xs) x xs

    = \c -> c x xs

Así que :

isEmpty lst
    = isEmpty (\c -> c x xs)
    =  (\c -> c x xs) (\x xs -> false)
    = false

    isEmpty []
    = isEmpty (\f -> true)
    = (\f->true) (\x xs -> false)
    = true

Ahora que podemos probar la lista vacía, podemos definir recursiones en listas como foldl, map, etc.

    foldl f acc lst =
      if isEmpty lst
        then acc
        else foldl f (f (head lst) acc) (tail lst)

y

    map f lst  =
      let
        map' f lst lst' = if isEmpty lst then (reverse lst') else map' f (tail lst) (head lst: lst')
      in
        map' f lst []

con

   reverse lst = (foldl (\acc elt -> (elt:acc)) [] lst

Las definiciones de foldl y map usan una expresión if-then-else que se define a posteriormente en condicionales.

 Concatenación de lista :   (++) lst1 lst2 = foldl (\acc elt -> (elt:acc)) lst2 (reverse lst1)

Para calcular la longitud de una lista necesitamos números enteros, se definen a continuación.

    length lst = foldl calc_length 0 lst
      where
        calc_length _ len = inc len

Hemos utilizado condicionales en las expresiones anteriores:

    if cond then if_true_exp else if_false_exp

Aquí cond es una expresión que devuelve verdadero o falso, que se definen a continuación.

Podemos escribir la cláusula if-then-else como una función pura:

    ifthenelse cond if_true_exp if_false_exp

Para evaluar la condición necesitamos definir booleanos:

    true = \x y -> x
    false = \x y -> y


Con esta definición, el if-then-else se convierte simplemente

    ifthenelse cond if_true_exp if_false_exp = cond if_true_exp if_false_exp

Usando ifthenelse podemos definir y, o y no:

    and x y = ifthenelse x (ifthenelse y true) false
    or x y = ifthenelse x true (ifthenelse y true false)
    not x = ifthenelse x false true

Observamos que para probar la igualdad de los booleanos podemos usar xnor y, por supuesto, podemos definir xor en términos de y, o y no:

    xor x y = (x or y) and (not x or not y)
    xnor x y = not (xor x y)

Enteros firmados
Definimos un entero como una lista de valores booleanos, en codificación de termómetro, y con las siguientes definiciones:

Definimos usigned 0 como una lista de 1 elemento que contiene false. Para obtener enteros con signo, simplemente definimos el primer bit de la lista como el bit de signo. Definimos versiones firmadas y sin firmar de 0:

    u0 = false:[]
    0 = +0 = true:u0
    -0 = false:u0

Por conveniencia definimos también:

    isPos n = head n
    isNeg n = not (head n)
    isZero n = not (head (tail n))
    sign n = head n

La definición de 0 facilita la igualdad de enteros (==):

    (==) n1 n2 = let
      s1 = head n1
      s2 = head n2
      b1 = head (tail n1)
      b2 = head (tail n2)
      if (xnor s1 s2) then
        if (and (not b1) (not b2))
          then true
          else
            if (and b1 b2)
              then  (==) (s1:(tail n1)) (s2:(tail n2))
              else false
        else false


También podemos definir fácilmente la negación:

    neg n = (not (head n)):(tail n)

Por conveniencia definimos también definimos operaciones de incremento y decremento:

    inc n = if isPos n then true:true:(tail n) else if isZero n then 1 else false:(tail (tail n))
    dec n = if isZero n then -1 else if isNeg n then false:true:(tail n) n else true:(tail (tail n))

La adición general es bastante fácil:

    add n1 n2 = foldl add_if_true n1 n2
      where
        add_if_true elt n1 = if elt then true:n1 else n1

Del mismo modo, la resta también es sencilla:

    sub n1 n2 = foldl sub_if_true n1 n2
      where
        sub_if_true elt n1 = of elt then (tail n1) else n1

Una forma sencilla de definir la multiplicación es definiendo las operaciones de replicación y suma:

    replicate n m =
      let
        repl n m lst = if n==0 then lst else repl (dec n) m (m:lst)
      in
        repl n m []

    sum lst = foldl add 0 lst

Entonces la multiplicación simplemente se convierte en

    mult n m = sum (replicate n m)

De manera similar, se pueden definir la división y el módulo de enteros.

Observamos que los flotantes y los caracteres utilizan una representación de números enteros, y las cadenas son simplemente listas de caracteres. Entonces ahora tenemos un lenguaje que puede manipular listas y tuplas de enteros, flotantes, caracteres y cadenas.

Introspección de objetos en Python


En programación, la introspección es la capacidad de determinar las características de un objeto en tiempo de ejecución. Es uno de los puntos fuertes de Python. Todo en Python es un objeto y podemos examinar esos objetos. Python viene con algunas funciones y módulos incorporados para ayudarnos.

dir es una de las funciones más importantes para la introspección. Devuelve una lista de atributos y métodos que pertenecen a un objeto. Aquí hay un ejemplo:

my_list = [1, 2, 3]

dir(my_list)

# Output: ['__add__', '__class__', '__contains__', '__delattr__', '__delitem__',

# '__delslice__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__',

# '__getitem__', '__getslice__', '__gt__', '__hash__', '__iadd__', '__imul__',

# '__init__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__',

# '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__',

# '__setattr__', '__setitem__', '__setslice__', '__sizeof__', '__str__',

# '__subclasshook__', 'append', 'count', 'extend', 'index', 'insert', 'pop',

# 'remove', 'reverse', 'sort']

Esta llamada nos dio los nombres de todos los métodos de una lista. Esto puede ser útil cuando no puede recordar el nombre de un método. Si ejecutamos dir () sin ningún argumento, devuelve todos los nombres en el ámbito actual.

La función de type devuelve el tipo de un objeto. Por ejemplo:

print(type(''))

# Output: <type 'str'>

print(type([]))

# Output: <type 'list'>

print(type({}))

# Output: <type 'dict'>

print(type(dict))

# Output: <type 'type'>

print(type(3))

# Output: <type 'int'>

id devuelve los identificadores únicos de varios objetos. Por ejemplo:

name = "Yasoob"

print(id(name))

# Output: 139972439030304

El módulo de inspección también proporciona varias funciones útiles para obtener información sobre objetos activos. Por ejemplo, puede verificar los miembros de un objeto ejecutando:

import inspect
print(inspect.getmembers(str))
# Output: [('__add__', <slot wrapper '__add__' of ... ...

También hay un par de otros métodos que ayudan en la introspección. Pero los veremos en otro post...

miércoles, 4 de noviembre de 2020

Libros Gratuitos de Java Code Geeks

 

Download IT Guides!

 

Java 8 Features

With no doubts, Java 8 release is the greatest thing in the Java world since Java 5 (released quite a while ago, back in 2004). It brings tons of new features to the Java as a language,...

 
 

Amazon DynamoDB Tutorial

Amazon DynamoDB is a fully managed proprietary NoSQL database service that is offered by Amazon.com as part of the Amazon Web Services portfolio...

 
 

Mockito Programming Cookbook

Mockito is an open source testing framework for Java released under the MIT License. The framework allows the creation of test double objects (mock objects) in automated unit tests for...

 
 

Vaadin Programming Cookbook

Vaadin is an open source web framework for rich Internet applications. In contrast to JavaScript libraries and browser-plugin based solutions, it features a server-side architecture,...

 

martes, 3 de noviembre de 2020

Elixir School


Elixir School es el primer destino para personas que buscan aprender y dominar el lenguaje de programación Elixir

Ya seas un veterano experimentado o esta es tu primera vez, vas a encontrar lo que necesitas en las lecciones y en los recursos auxiliares

Mediante el trabajo duro de voluntarios Elixir School ha sido traducido a muchos idiomas. Algunas de estas traducciones incluyen: Việt ngữ, 简体中文, 繁體中文, English, Slovenčina, 日本語, Polski, Português, Русском, Bahasa Indonesia, Bahasa Melayu, Українською, 한국어, Italiano, Deutsch, বাংলা, Türkçe, y ภาษาไทย.

Te damos la bienvenida y te motivamos a continuar haciendo Elixir School grandioso involucrándote en elixirschool/elixirschool!

De esta manera se presenta Elixir school que es un excelente sitio para comenzar con Elixir. 

Y sin más dejo link: https://elixirschool.com/es/

lunes, 2 de noviembre de 2020

Tipos con Clase parte 5



Seguimos con type class

Veamos algunas de type class definidas en las bibliotecas estándar.

Num: números, con muchas subclases para tipos específicos de números.

Read: tipos que se pueden "leer desde" una cadena.

Show: tipos que se pueden "mostrar a" una cadena.

Eq: tipos para los que se define el operador de igualdad ==.

Ord: tipos para los que puede hacer comparaciones como <,>, etc.

Enum: tipos donde los valores se pueden enumerar en secuencia; esto se usa, por ejemplo, en la notación [1..n] y ′ a ′ .. ′ z ′.

    *Main> [1..10]

    [1,2,3,4,5,6,7,8,9,10]

    *Main> ['a'..'z']

    "abcdefghijklmnopqrstuvwxyz"

Tipos con Clase parte 4


Seguimos con Type class

Hemos estado usando show para convertir un valor de datos en una cadena, que luego se puede escribir en la salida.

Algunos valores se pueden "mostrar", pero no todos.

Por ejemplo, en general es imposible mostrar una función.

Por lo tanto, debemos usar type class

    show::Show a → a→String

Definición de su propia instancia de Show

    data Foo = Bar | Baz

Podríamos querer nuestra propia representación de cadena :

    instance Show Foo where

      show Bar = "it is a bar"

      show Baz = "this is a baz"


Recordemos que cuando ingresa una expresión exp en ghci, imprime showexp. Entonces podemos probar nuestra extraña declaración de instancia:

    *Main> Bar

    it is a bar

    *Main> Baz

    this is a baz


deriving nos permite indicar que "implementa" Show o otro data type : 

    data Foo2 = Bar2 | Baz2

      deriving (Read, Show)

Haskell definirá automáticamente una instancia de show para Foo2, usando la definición obvia:

    *Main> Bar2

    Bar2

    *Main> Baz2

    Baz2


domingo, 1 de noviembre de 2020

Tipos con Clase parte 3

 


Seguimos con type class

Haskell proporciona varias type class estándar. Echemos un vistazo a Num.

Num es la clase de tipos numéricos.

Aquí está (en parte) su declaración de clase:

    class Num a where

      (+), (-), (*) :: a -> a -> a

Hay muchos tipos numéricos; dos de ellos son Int y Double.

Hay funciones monomórficas primitivas que realizan operaciones aritméticas en estos tipos (estos no son los nombres reales):

addInt, subInt, mulInt :: Int -> Int -> Int

addDbl, subDbl, mulDbl :: Double -> Double -> Double


    instance Num Int where

      (+) = addInt

      (-) = subInt

      (*) = mulInt


    instance Num Double where

      (+) = addDbl

      (-) = subDbl

      (*) = mulDbl


Hay algunas operaciones (suma) que son válidas para todos los tipos numéricos. Hay algunos otros (por ejemplo, funciones trigonométricas) que son válidos solo para algunos tipos numéricos.

Por lo tanto, existe una rica jerarquía de subclases, que incluyen :

Integral: clase de tipos numéricos que representan valores enteros, incluidos Int, Integer y más.

Fraccional: clase de tipos que pueden representar fracciones.

Floating: clase que contiene Float, Double, etc.

Bounded: clase de tipos numéricos que tienen un elemento mínimo y máximo.

Bits: clase de tipos donde puede acceder a la representación como una secuencia de bits, útil para la programación de sistemas y el diseño de circuitos digitales.

Si deseamos profundizar en clases y tipos numéricos, podemos consultar la documentación de Haskell.


Tipos con Clase parte 2


Seguimos con type class

Un Type Class es un conjunto de tipos para los que se definen algunas operaciones.

Haskell tiene algunas Type Classes estándar que se definen en el Preludio estándar.Pero también podemos definir el tuyo propio.

Supongamos que estamos computando con colores. Aquí hay un tipo y un par de funciones.

    data Bright = Blu | Red

      deriving (Read, Show)


    darkBright :: Bright -> Bool

    darkBright Blue = True

    darkBright Red  = False


    lightenBright :: Bright -> Bright

    lightenBright Blue = Red

    lightenBright Red = Red


Ahora, suponga que tenemos un tipo diferente que necesita funciones similares.


    data Pastel  = Turquoise  | Tan

      deriving (Read, Show)


    darkPastel :: Pastel -> Bool

    darkPastel Turquoise = True

    darkPastel Tan       = False


    lightenPastel :: Pastel -> Pastel

    lightenPastel Turquoise = Tan

    lightenPastel Tan       = Tan


Ambos tipos de colores tienen funciones para decidir si es oscuro o claro.

Podemos definir una clase Color y sus funciones correspondientes.

    class Color a where

      dark :: a -> Bool

      lighten :: a -> a


Esto dice :

  • El color es una clase de tipo
  • La variable de tipo a representa un tipo particular que está en la clase Color
  • Para cualquier tipo a en Color, hay dos funciones que puede usar: oscuro y claro, con los tipos especificados.

Una declaración de instancia dice que un tipo es miembro de una clase de tipo.

Cuando declaras una instancia, necesitas definir las funciones de clase.

A continuación se indica que el tipo Bright está en la clase Color y, en ese caso, la función oscura es en realidad darkBright.

    instance Color Bright where

      dark = darkBright

      lighten = lightenBright


De manera similar, podemos declarar que Pastel está en Color, pero tiene diferentes funciones para implementar las operaciones de la clase.

    instance Color Pastel where

      dark = darkPastel

      lighten = lightenPastel



Tipos con Clase


Type class son una forma de sobrecargar funciones u operadores al imponer restricciones al polimorfismo.

Por ejemplo:

(+) :: a -> a -> a

no está bien porque queremos restringir la suma de números.

Igualmente,

     (<) :: a -> a -> Bool

no está bien porque no está claro a priori cómo comparar con tipos arbitrarios.

Para abordar este problema, Haskell proporciona Type class. Estos restringen el polimorfismo. Por ejemplo:

     (+) :: Num a => a -> a -> a

dice que el tipo a debe ser numérico, y

     (<) :: Ord a => a -> a -> Bool

dice que debe ser ordenable.

Y eso es todo! listo, pero pero puedo crear mi propio type class? Lucho, por supuesto viejo... pero lo vamos a ver en el próximo post. 



viernes, 30 de octubre de 2020

Zip y unzip en python


Zip es una función útil que le permite combinar dos listas fácilmente. Como un cierre.

Después de llamar a zip,obtenemos un iterador. Para ver el contenido envuelto dentro, primero debemos convertirlo en una lista.

Ejemplo:


first_name = ['Joe','Earnst','Thomas','Martin','Charles']

last_name = ['Schmoe','Ehlmann','Fischer','Walter','Rogan','Green']

age = [23, 65, 11, 36, 83]

print(list(zip(first_name,last_name, age)))

# Output

#

# [('Joe', 'Schmoe', 23), ('Earnst', 'Ehlmann', 65), ('Thomas', 'Fischer', 11), ('Martin', 'Walter', 36), ('Charles', 'Rogan', 83)]


Una ventaja del zip es que mejora la legibilidad de los bucles for.

Por ejemplo, en lugar de necesitar varias entradas, solo necesita una lista zip para el siguiente bucle for:


first_name = ['Joe','Earnst','Thomas','Martin','Charles']

last_name = ['Schmoe','Ehlmann','Fischer','Walter','Rogan','Green']

age = [23, 65, 11, 36, 83]

for first_name, last_name, age in zip(first_name, last_name, age):

    print(f"{first_name} {last_name} is {age} years old")


# Output

#

# Joe Schmoe is 23 years old

# Earnst Ehlmann is 65 years old

# Thomas Fischer is 11 years old

# Martin Walter is 36 years old

# Charles Rogan is 83 years old


También podemos usar la función zip para abrir el cierre o hacer unzip . Esta vez, necesitamos la entrada de una lista con un asterisco antes.

Las salidas son listas separadas.


full_name_list = [('Joe', 'Schmoe', 23),

                  ('Earnst', 'Ehlmann', 65),

                  ('Thomas', 'Fischer', 11),

                  ('Martin', 'Walter', 36),

                  ('Charles', 'Rogan', 83)]


first_name, last_name, age = list(zip(*full_name_list))

print(f"first name: {first_name}\nlast name: {last_name} \nage: {age}")


# Output


# first name: ('Joe', 'Earnst', 'Thomas', 'Martin', 'Charles')

# last name: ('Schmoe', 'Ehlmann', 'Fischer', 'Walter', 'Rogan')

# age: (23, 65, 11, 36, 83)


miércoles, 28 de octubre de 2020

apuntes.de


Quiero recomendarles este sitio que esta en español y tienen varios libros gratuitos sobre tecnología. Que temas pueden encontrar?? 

  •  AWS (Fundamentos Prácticos)
  • AWS (Cloud Practitioner CLF-C01)
  • AWS (Certificación CSSA)
  • Bitcoins (Criptomonedas)
  • Código Limpio (Desarrollo Ágil de Software)
  • Docker (Certificación DCA)
  • Electron (Desarrollo de aplicaciones de escritorio con JavaScript)
  • Emprendimiento (Creación de Startups)
  • Golang (Desde Cero)
  • Ionic (Desarrollo de aplicaciones multiplataforma con JavaScript)
  • Linux (Certificación LPI)
  • NodeJS (Desde Cero)
  • NodeJS (Desarrollo Web)
  • Python (Certificación PCEP)
  • Ruby (Curso en Español desde Cero)
  • Entrenamiento SEO (Search Engine Optimizacion)
  • Fundamentos de SEO (Search Engine Optimization)

sin más : https://apuntes.de

martes, 27 de octubre de 2020

Tour of Scala

Quiero compartirles esta pagina que nos hace un tour por el maravilloso mundo de scala por medio de ejercicios que deberás resolver. 

Dejo link: https://tourofscala.com/