Я пытаюсь расширить игрушечный пример, описанный в этом блоге. сообщение.
{-# LANGUAGE DeriveFunctor #-}
{-# LANGUAGE FlexibleContexts #-}
module FreeToy where
import Control.Monad.State
import Control.Monad.Free
import Data.Map (Map)
import qualified Data.Map as M
-- defining commands
data Toy a next =
Output a next
| AnnoyingOutput a (String -> next)
| Done
deriving (Functor)
-- lifing commands to free monad level
output :: a -> Free (Toy a) ()
output x = liftF $ Output x ()
annoyingOutput :: a -> Free (Toy a) {-some type-}
annoyingOutput x = liftF $ AnnoyingOutput x {-some function-}
done :: Free (Toy a) r
done = liftF $ Done
-- defining one of the interpreter
runToy :: (Show a, Show r) => Free (Toy a) r -> String
runToy (Free (Output a x)) =
"output " ++ show a ++ "\n" ++ runToy x
runToy (Free (AnnoyingOutput a f)) =
"annoying output " ++ show a ++ runToy (f "blah blah blah \n")
runToy (Free Done) =
"done\n"
runToy (Pure r) =
"return " ++ show r ++ "\n"
Я попытался добавить новую вещь: AnnoyingOutput a (String -> next)
это возьмет что-то и вернет строковое сообщение. Я создаю структуру, поднимая ее на уровень Free monad с помощью функции liftF
. Пожалуйста, помогите мне заполнить пробелы, и правильное объяснение заметно.
Изменить: добавление примера
module Main where
import FreeToy
import Control.Monad.Free
program :: Free (Toy String) ()
program = do
output "something"
x <- annoyingOutput "something else"
output x
done
main :: IO ()
main = putStrLn $ runToy program
String
, а функцияid
, но я не уверен - person Bergi   schedule 05.09.2016runToy
, кажется, пропустил делоPure
- person Bergi   schedule 05.09.2016runToy
Ошибки: 1. Не удалось сопоставить ожидаемый тип «Free (Toy a) r -> String» с фактическим типом «[Char]» 2. Не удалось сопоставить ожидаемый тип «[Char]» с фактическим type 'Free (Toy a0) r0 -> String' - person venu gangireddy   schedule 05.09.2016annoyingOutput
, в ответе на этот связанный вопрос.annoyingOutput
будет выглядеть какadd
. - person Cirdec   schedule 05.09.2016$
вrunToy $ f "blah blah blah \n"
следует заменитьrunToy (f "blah blah blah \n")
- person Michael   schedule 06.09.2016annoyingOutput :: a -> Free (Toy a) String; annoyingOutput x = liftF $ AnnoyingOutput x id
. Это означает, что правильно функция запуска должна иметь доступ к источнику строк, где вы просто продолжаете кормить его"blah blah blah \n"
- person Michael   schedule 06.09.2016runToy $ f "blah blah blah \n"
следует заменитьrunToy (f "blah blah blah \n")
? вообще$
и()
можно заменить, почему в данном случае по другому? - person venu gangireddy   schedule 06.09.2016$
мешает тому, что вы хотите, что-то вроде... ++ ... ++ ...
$
имеетinfixr 0
, поэтому ghc читает его как доминирующую связку в выражении, так что что-то в форме... $ ...
что тогда он может 'Т понять. Вы хотите, чтобы $ был ограничен последней добавленной вещью - вы также можете написать(runToy $ f "blah blah blah \n")
для управления$
, но как только вы используете круглые скобки, вы можете также поместить их вокруг(f "blah ..)
. Вы можете запросить приоритет в ghci с помощью:i ++
или:info $
и т.п. - person Michael   schedule 06.09.2016