hacer - Haskell donde la sintaxis de la cláusula dentro de un bloque do
if en haskell ejemplos (3)
¿No debería estar en su where
al final de la función?
Me gusta esto:
function aList aValue = do
mapM_ func aList
return aValue
where func x = x + 1
Estoy tratando de refactorizar una mapM_
función mapM_
dentro de un bloque do
en Haskell. Me gustaría extraer la lambda a una función con nombre (localmente) para hacer que el código sea más legible.
Mi código originalmente se ve así:
do
-- ...
mapM_ (/x -> x + 1) aList
return aValue
Me gustaría cambiarlo a
do
-- ...
mapM_ func aList
where func x = x + 1
return aValue
pero estoy recibiendo un error de sintaxis en la línea de return aValue
. Mi lambda real es más complicada :-), pero la probé con esta misma lambda para asegurarme de que no era un problema en el código lambda.
¿Cómo puedo reescribir este código? ¿Debo usar let
... in
lugar?
Hay tres formas similares (pero distintas) de definir cosas aquí:
Puede adjuntar las cláusulas
where
después de ciertas definiciones, principalmente enlaces de estilo de ecuación. Así que podría poner uno al final de su función, o después de algo definido conlet
o una cláusula circundantewhere
.Por otro lado,
let x = ... in ...
es una expresión que se evalúa en la parte posteriorin
, que es el único lugar en ellet
se puede ver el contenido después delet
.Dentro de un bloque
do
, debido a que ya hay un anidado implícito de alcance (las cosas son visibles después de que se definieron por primera vez), puede usar sololet x = ...
solo. Esto es realmente lo mismo que en la forma anterior: el resto del bloquedo
después delet
es efectivamente la partein ...
Si desea una definición local que use algo definido dentro del bloque do
, su única opción es la tercera (o pasar el otro valor (es) como argumento (s)). Sin embargo, para un ayudante independiente funciona como su ejemplo, cualquier estilo funciona. Aquí está tu ejemplo, para demostrar cada uno:
El primer estilo, donde func
es visible en cualquier parte de foo
, incluyendo cualquier otra cosa definida en la cláusula where
:
foo = do ...
mapM_ func aList
...
return aValue
where func x = x + 1
El segundo estilo, donde func
solo es visible dentro de la expresión let
, que en este caso es el bloque do
completo:
foo = let func x = x + 1
in do
...
mapM_ func aList
...
return aValue
Y el tercer estilo, definiéndolo dentro del bloque do
. En este caso, func
solo es visible después de let
; En la primera ...
aún no se ha definido.
foo = do ...
let func x = x + 1
mapM_ func aList
...
return aValue
Ah, y por si acaso, ya que let ... in ...
es una expresión, también puede usarla en cualquier lugar donde tenga una expresión, para nombrar algunas definiciones locales. Así que aquí hay otro ejemplo:
foo = do ...
let func x = x + 1 in mapM_ func aList
...
return aValue
Como antes, func
solo es visible dentro de la expresión let
, que en este caso es la única expresión posterior a ella, en ninguna otra parte.
Otra opción es usar forM_
lugar de mapM_
, que cambia el orden de los argumentos. Luego puede usar el operador $
con una expresión lambda al final como la siguiente:
do
forM_ aList $ /x -> do
...
return aValue