haskell:依赖注入的reader-monad

时间:2018-11-13 15:38:43

标签: haskell dependency-injection

我从learnyouahaskell书中获得了读者单子的基本功能,并且我在这里看到了一些建议,可以将其用于依赖项注入。 即使在stackoverflow上有一些示例,我也不知道如何使用它进行集成测试。

我的代码是:

list :: Ctx -> [String] -> IO String
list ctx args = do
    d <- eitherDecode <$> Uplink.get (token ctx) (endpointActivities ctx) :: IO (Either String Activities)
    case d of 
        Left err -> return err 
        Right result -> return $ unlines . filterByPrefix (parsePrefix args) . extractNames $ activities result

uplink.hs

get :: String -> String -> IO B.ByteString
get token endpoint = do
    req <- parseRequest endpoint
    resp <- httpLBS $ withAuth token req
    return $ getResponseBody resp

我如何模拟 httpLBS -要求使用reader-monad进行集成测试?


编辑:!!!!

我现在几乎可以通过读者单子获得它。剩下的唯一问题是我不知道如何在Ctx数据类型中定义httpsLBS函数。

httpLBS -功能签名:

httpLBS :: MonadIO m => Request -> m (Response ByteString) 

我的Ctx数据类型定义:

data Ctx =
    Ctx {
        token :: String,
        endpointActivities :: String,
        endpointTimeTrackingStart :: String,
        httpLBSFunc :: MonadIO m => Request -> m (Response ByteString)
    } deriving (Show)

我总是会收到错误:不在范围内:输入变量“ m” 如何使用约束将其定义为Ctx数据类型?

我保证,当最后一个问题解决后,我会在以后发布我的解决方案

1 个答案:

答案 0 :(得分:0)

在Haskell中,依赖项注入只是高阶编程+柯里化。您可以按照以下方式编写代码。

-- where (? -> ?) is the type of httpLBS
get_ :: (? -> ?) -> String -> String -> IO B.ByteString
get_ httpFunc token endpoint = do
    req <- parseRequest endpoint
    resp <- httpFunc $ withAuth token req
    return $ getResponseBody resp

getProduction = get_ httpLBS

getTest = get_ httpMock