Haskell Hero

Haskell Hero es un manual interactivo del lenguaje Haskell para principiantes.

curry, uncurry

Para empezar

Sabemos que existen funciones binarias. Por ejempo (+), (-) o const. Después también hay funciones unarias que toman una dupla como parámetro. Por ejemplo fst o snd.

Podemos ver que funciones const y fst funcionan de manera similar. const x y evalúa a su primer parámetro x, fst (x,y) evalúa al primer elemento de su parámetro, es decir, a x.

Ya que las dos funciones son simples, podemos en general definirlas bien sin tener que definirlas por medio de la otra función. Sin embargo, algunas veces es más útil usar funciones curry o uncurry en la definición.

curry

curry es una función ternaria. Toma como parámetros:

  • una función unaria f que toma como parámetro una dupla, de tipo (a,b) -> c
  • x de tipo a que puede tomar la función f como su primer parámetro
  • y de tipo b que puede tomar la función f como su segundo parámetro

Cuando se evalúa la función curry, por ejemplo en la expresión curry f x y, los parámetros x y y se convierten en una dupla (x,y) y la función f toma esta dupla como su parámetro. El resultado es de tipo c.

Definición

curry       ::  ((a,b) -> c) -> a -> b -> c
curry f x y  =  f (x,y)

Ejemplos

curry fst  5  True   ~>  fst (5,True)     ~>  5
curry snd 'y' "bbb"  ~>  snd ('y',"bbb")  ~>  "bbb"

uncurry

La función uncurry funciona al revés. Es una función binaria que toma como parámetros:

  • una función binaria f de tipo a -> b -> c
  • una dupla (x,y) de tipo (a,b) en la que el primer elemento se puede usar como el primer parámetro de la función f y el segundo elemento como el segundo parámetro de la función f.

Cuando se evalúa la función uncurry, por ejemplo la expresión uncurry f (x,y), la dupla se convierte en dos parámetros individuales x y y y después se aplica la función f a estos parámetros.

Definición

uncurry         ::  (a -> b -> c) -> (a,b) -> c
uncurry f (x,y)  =  f x y

Ejemplos

uncurry const (False,8)  ~>  const False 8  ~>  False

uncurry (flip const) ("ccc",'a')
  ~>  flip const "ccc" 'a'
  ~>  const 'a' "ccc"
  ~>  'a'