-
Notifications
You must be signed in to change notification settings - Fork 0
Open
Description
- Escrever primeiro batch de tutoriais (só vamos entender o que é preciso se implementarmos a ideia)
learnyouhaskelllearnyouworkhs
- Mais type-safe
- Interface melhor
- O
list-promptprecisa conseguir se renderizar propriamente independente do tamanho do terminal
- O
- i18n
- Helpers para escrever tutoriais
- verifica o output
- roda IO e retorna um boolean
- roda uma suite de testes do hspec contra uma função do módulo
- roda uma suite de testes do hspec, tendo a execução/output do módulo fornecido de uma forma simples por outro helper
Tutoriais interativos de fato
Recentemente, brinquei com a ideia de rodar um GHCi como um sub-processo de um programa. Fiz isso para tentar fazer o ghci um pouco melhor. Acho que seria divertido poder lançar uma sessão do GHCi que fosse controlada pelo tutorial que está rodando. Tipo:
$ learnyouhaskell
Bellow is a live REPL. Try pressing enter.
ghci> putStrLn "something"<imagine-que-pressiona-enter>
"something"
Cool, that's what I wanted. Now what about doing a `map`?
The type of map is:
ghci> :t map
map :: (a -> b) -> [a] -> [b]
Try it yourself:
ghci> <cursor-esta-aqui>
Imagine que temos algo como:
uiThread rc wc ewc = do
_ <- forkIO $ forever $ do
b <- atomically (readTChan wc)
ByteString.putStr b
_ <- forkIO $ forever $ do
b <- atomically (readTChan ewc)
ByteString.hPutStr stderr b
loop
where
loop = do
eof <- hIsEOF stdin
unless eof $ do
b <- ByteString.getLine
atomically (writeTChan rc (b <> "\n"))
loopE menos sucetíveis a erros, claro. O que essa função faz é ler texto de dois canais e imprimir ele na tela. E aí podemos ter outra função:
ghciThread :: TChan ByteString -> TChan ByteString -> TChan ByteString -> IO ()
ghciThread rc wc ewc = do
(inp, out, err, cph) <- ghciStreamingProcess
readerTid <- forkIO $ chanSource readTChan rc `connect` inp
outWriterTid <- forkIO $ out `connect` Conduit.ByteString.lines `connect` chanSink writeTChan wc
errWriterTid <- forkIO $ err `connect` chanSink writeTChan ewc
e <- waitForStreamingProcess cph
return ()Que publica o GHCi nesses canais; dependendo de:
chanSource read c = go
where
go = do
x <- liftIO (atomically (read c))
Conduit.yield x
go
chanSink write c = Conduit.List.mapM_ $ liftIO . atomically . write cMetadata
Metadata
Assignees
Labels
No labels