Supongamos que tengo una función con la firma siguiente tipo:Utilización de los elementos en una lista como argumentos
g :: a -> a -> a -> b
que también tienen una lista de a
s-llamémoslo xs
-que sé que van a contener al menos tres artículos. Me gustaría aplicar g
a los primeros tres elementos de xs
. Sé que podría definir un combinador como la siguiente:
($$$) :: (a -> a -> a -> b) -> [a] -> b
f $$$ (x:y:z:_) = f x y z
Entonces podría simplemente utilizar g $$$ xs
. Esto hace que $$$
sea un poco como uncurry
, pero para una función con tres argumentos del mismo tipo y una lista en lugar de una tupla.
¿Hay alguna manera de hacer esto idiomáticamente con los combinadores estándar? O mejor dicho, ¿cuál es la forma más idiomática de hacer esto en Haskell? Pensé que intentar pointfree
en una versión no infija de $$$
podría darme una idea de por dónde empezar, pero la salida era una abominación con 10 flip
s, un puñado de head
sy tail
sy ap
s, y 28 paréntesis.
(NB: Sé que esto no es terriblemente una cosa de Haskelly para hacer, en primer lugar, pero he encontrado un par de situaciones en las que parece una solución razonable, especialmente cuando se usa Parsec. ciertamente aceptar "no siempre hacer esto en código real" si esa es la mejor respuesta, pero yo prefiero ver algunos truco inteligente que implica la mónada ((->) r)
o lo que sea.)
No veo cuál es el problema con el código que tiene. Es corto y al grano. No todo tiene que ser (o debería ser) sin punto. – sepp2k
No creo necesariamente que haya nada de malo en ello: solo tengo curiosidad acerca de si hay una forma concisa de hacer esto sin definir un nuevo combinador como '$$$'. –
Tenga en cuenta que esta es una función parcial, por lo que ... probablemente sea una mala idea en general :) Puede que sea mejor con un '($$$) :: (a -> a -> a -> b) -> [a] -> Tal vez b' –