2015-07-27 18 views
5

Ho il seguente codice sempliceQual è il modo giusto per gestire i funtori (profondamente annidati)?

import Data.String.Regex 
import Data.Array 

last <$> match someRegex " 1" 

dove

match someRegex " 1" 

restituisce qualcosa come

Just ([Just (" 1"),Just (" "),Just ("1")]) 

e

last <$> match someRegex " 1" 

restituisce qualcosa lik e

Just (Just (Just (" 1"))) 

Ora ho un Forse profondamente annidato. Il che rende difficile lavorare con (anche usando i funtori). Mi sono scritto un paio di funzioni di supporto - ma sono un po 'infelice. In qualche modo non sembra giusto.

extract j = do 
    case j of 
     Nothing -> Nothing 
     Just a -> a 
extract2 jj = extract $ extract jj 

E poi usarlo come questo

extract2 $ last <$> match someRegex " 1" 

C'è un/modo migliore idiomatica per fare queste cose in Purescript/Haskell?

+2

Se non vuoi ancora unirti, ma vuoi cambiarlo, ricorda che fmap è componibile: 'fmap. fmap :: (Functor f, Functor g) => (a -> b) -> f (g a) -> f (g b) ',' fmap. fmap. fmap :: (Functor f, Functor g, Functor h) => (a -> b) -> f (g (ha)) -> f (g (hb)) ' – Cubic

+0

hmm la mia domanda era più se c'è un modo per evitare questo nidificazione in primo luogo – robkuz

+1

Con 'Maybe' ci sono poche informazioni interessanti codificate in più livelli, ma questo potrebbe non essere il caso con altri funtori (ad esempio si potrebbe usare' fmap. fmap. fmap' per mappare su una lista doppiamente annidata pur conservando tutta la sua struttura). – duplode

risposta

9

Forse siete alla ricerca per la funzione join:

http://pursuit.purescript.org/packages/purescript-control/0.3.0/docs/Control.Bind#d:join

join crolla due strati di una struttura fino a un singolo strato, che unisce tutti gli effetti. Nel caso di Maybe, ciò significa che il valore risultante non sarà Nothing solo se entrambi i livelli non erano Nothing.

+0

quindi in pratica stai dicendo che la mia funzione 'extract' è una variante di' join' e che è il modo in cui vengono gestite le cose? duh! Non esiste un modo (concettualmente) per evitare quella nidificazione profonda in primo luogo? – robkuz

+3

Un modo è di notare che 'join (map fx)' è lo stesso di 'x >> = f' secondo le leggi di' Monad', quindi potresti dire 'match someRegex" 1 ">> = last' e salvare te stesso un 'join'. –

+0

'match' restituisce due strati di' Maybe' a causa dei molteplici modi in cui la versione di JS può fallire, quindi almeno un 'join' è necessario se ci si preoccupa che tutto abbia successo. –