gpt4 book ai didi

haskell - 如何不对使用更通用函数的受限函数应用实例约束?

转载 作者:行者123 更新时间:2023-12-02 01:49:59 26 4
gpt4 key购买 nike

假设我有一个功能:

logResult :: (MonadIO m, ToJSON a) => Either MyError (Response a) -> m ()
logResult = ...

在这个函数中,如果我得到:
  • Right (Response a) - 我调用 toJSON记录结果。
  • Left MyError - 我也记录下来。 MyError已有 ToJSON实例定义。

  • 现在我想写一个辅助函数:

    logError :: (MonadIO m) :: MyError -> m ()
    logError err = logResult (Left err)

    但 GHC 提示如下:
        • Could not deduce (ToJSON a0) arising from a use of ‘logResult’                                                                    
    from the context: MonadIO m
    bound by the type signature for:
    logError :: forall (m :: * -> *).
    MonadIO m =>
    L.Logger
    -> Wai.Request
    -> MyError
    -> m ()

    ...
    ...
    The type variable ‘a0’ is ambiguous

    我理解错误是因为 logResult需要保证 aResponse a必须有 ToJSON实例定义。但是在 logError我明确通过 Left MyError .这不应该消除歧义吗?

    有什么办法可以写 logError辅助功能?

    PS:我已经简化了示例中的类型签名。错误消息有血淋淋的细节。

    最佳答案

    为什么这是一个功能?如果这个函数的行为如此干净地分成两个,那么它应该是两个函数。也就是说,您已经编写了一个整体函数,并试图将一个更简单的函数定义为使用它的实用程序。相反,编写一个简单的函数并将单体函数编写为它与另一个函数的组合。该类型非常需要它:Either a b -> c(a -> c, b -> c) 同构.

    -- you may need to factor out some common utility stuff, too
    logError :: (MonadIO m) :: MyError -> m ()
    logResponse :: (MonadIO m, ToJSON a) => Response a -> m ()

    logResult :: (MonadIO m, ToJSON a) => Either MyError (Response a) -> m ()
    logResult = either logError logResponse
    logResult仍然有它的用途;如果您收到 Either MyError (Response a)来自某个图书馆,然后是 logResult可以毫不费力地处理它。但是,否则,你不应该写 logResult (Left _)logResult (Right _)常常;本质上对待 logResult . LeftlogResult . Right作为它们自己的函数,这使您回到实际将它们编写为单独的函数。

    But in logError I am explicitly passing Left MyError. Shouldn't this disambiguate?



    不,不应该。问题的结束和开始是 logResult看起来像这样:
    logResult :: (MonadIO m, ToJSON a) => Either MyError (Response a) -> m ()

    当你调用它时,实现并不重要。类型说你需要 ToJSON a —您需要提供 ToJSON a .而已。如果你知道你不需要 ToJSON a对于 Left值,然后您拥有未反射(reflect)在类型中的有用信息。您应该将该信息添加到类型中,在这种情况下,这意味着将其分成两部分。 (IMO)实际上是错误的语言设计来允许您的想法,因为停止问题应该使其无法正确执行。

    关于haskell - 如何不对使用更通用函数的受限函数应用实例约束?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56283441/

    26 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com