2017-07-13 5 views
0

Pour en savoir un peu plus sur Turtle, j'ai pensé que ce serait bien de modifier l'exemple du tutoriel. J'ai choisi de supprimer le redondant "FilePath" de chaque ligne de la sortie en pensant que ce serait un exercice simple. Et pourtant, malgré les efforts de l'auteur pour rendre sa bibliothèque facile à utiliser, j'ai failli ne pas l'utiliser pour résoudre ce problème simple.Comment imprimer des chemins à l'aide de la bibliothèque Haskell Turtle?

J'ai essayé everyting j'ai vu qui semblait me permettre de soulever une certaine façon >>= de IO dans Shell: MonadIO, FoldM, liftIO, _foldIO sans succès. J'ai grandi frustré et seulement en lisant Turtle le code source j'ai pu trouver quelque chose qui semble fonctionner ("aucun défaut évident" ne vient à l'esprit).

Pourquoi est-ce si difficile? Comment arrive-t-on logiquement une solution en utilisant l'API de cette bibliothèque?

#!/usr/bin/env stack 
-- stack --resolver lts-8.17 --install-ghc runghc --package turtle --package lens 
{-# LANGUAGE OverloadedStrings #-} 
import Turtle 
import Control.Lens 
import Control.Foldl as Foldl 
import Filesystem.Path.CurrentOS 
import Data.Text.IO as T 
import Data.Text as T 

main = do 
    homedir <- home 
    let paths = lstree $ homedir </> "projects" 
    let t = fmap (Control.Lens.view _Right . toText) paths 
    customView t 

customView s = sh (do 
    x <- s 
    liftIO $ T.putStrLn x) 

Répondre

3

Vous ne soulevez pas >>= de IO dans Shell. Shell a déjà une instance Monad qui vient avec sa propre fonction >>=. Au lieu de cela, vous pouvez soulever IO actions dans Shell avec liftIO ou exécuter le shell avec fold ou foldM. Utilisez sh pour lancer le Shell lorsque vous ne vous souciez pas des résultats.

Je crois que votre exemple peut être simplifié pour

main = sh $ do 
    homedir <- home 
    filepath <- lstree $ homedir </> "projects" 
    case (toText filepath) of 
    Right path -> liftIO $ T.putStrLn x 
    Left approx -> return() -- This shouldn't happen 

En ce qui concerne la difficulté à obtenir une chaîne de retour d'une FilePath, je ne pense pas que cela puisse être attribué à l'auteur de la tortue. Je pense qu'il peut être simplifié à

stringPath :: FilePath -> String 
stringPath filepath = 
    case (toText filePath) of    -- try to use the human readable version 
    Right path -> T.unpack path 
    Left _  -> encodeString filePath -- fall back on the machine readable one 

Combiné cela simplifierait l'exemple

main = sh $ do 
    homedir <- home 
    filepath <- lstree $ homedir </> "projects" 
    liftIO $ putStrLn (stringPath filepath) 

ou

main = view $ do 
    homedir <- home 
    filepath <- lstree $ homedir </> "projects" 
    return $ stringPath filepath