haskell - 在Network.URI上无法匹配Maybe vs Maybe类型

标签 haskell types error-handling type-systems maybe

说我想使用https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html解析环境变量,并且默认情况下默认为localhost。

我可以这样写一个函数:

parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri

这很好。现在说我要处理错误。我注意到parseURI返回一个Maybe,表面上我只需要对此进行模式匹配。所以我创建了一个自定义错误:
data CustomError = MyCustomError Text deriving(Show)

我创建一个辅助函数:
parsedExtractor
  :: MonadError CustomError.MyCustomError m
  => Text
  -> Maybe URI.URI
  -> m(URI.URI)
parsedExtractor originalString Nothing = throwError $ FlockErrors.FailedToParseURI originalString
parsedExtractor _ (Just uri) = do
  pure uri

最后,我修改了初始功能:
parseRabbitURI :: MonadError CustomError.MyCustomError m => Text -> m(URI.URI)
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/" >>= parsedExtractor "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri >>= parsedExtractor uri

无法使用以下命令进行编译:
• Couldn't match type ‘URI.URI’ with ‘Maybe URI.URI’
  Expected type: URI.URI -> Maybe URI.URI
    Actual type: Maybe URI.URI -> Maybe URI.URI
• In the second argument of ‘(>>=)’, namely ‘parsedExtractor uri’
  In the expression: (URI.parseURI . toS) uri >>= parsedExtractor uri
  In an equation for ‘parseRabbitURI’:
      parseRabbitURI uri
        = (URI.parseURI . toS) uri >>= parsedExtractor uri

|
23 | parseRabbitURI uri =(URI.parseURI .toS)uri >> = parsedExtractor uri
|

对于我的一生,我不知道为什么。如果初始实现返回Maybe,为什么它将转换为无法通过的未包装URI.URI?

至关重要的是,当我更改parsedExtractor上的模式以期望字符串时,它也无法使用反消息编译(
Couldn't match expected type ‘URI.URI’
                      with actual type ‘Maybe URI.URI’

我觉得我一定错过了一些根本的东西。这里发生了什么?

最佳答案

And for the life of me I can't figure out why. If the initial implementation returns a Maybe, why is it converting to an unwrapper URI.URI which I can't then pass?



要从Control.Monad引用>>=的定义,其类型为signture:
(>>=) :: m a -> (a -> m b) -> m b

现在,与表达式进行比较:
(URI.parseURI . toS) uri >>= parsedExtractor uri

我们有:
m a        ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri

由于(URI.parseURI . toS) uri返回类型Maybe URI.URIMaybeMonad的实例,因此
m a ~ Maybe URI.URI 


(a -> m b) ~ (URI.URI -> m b) 

m b可以推断为m (URI.URI),因此parsedExtractor uri之后的函数(即>>=)的类型应为:
(URI.URI -> m (URI.URI))

但实际并非如此。

关于haskell - 在Network.URI上无法匹配Maybe vs Maybe类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53407890/

相关文章:

parsing - Haskell 中 read 函数的大小写匹配

haskell - Haskell 中的柯里化(Currying)如何与 lambda 一起使用?

Java:参数实现的内部类中不需要的类型删除

c# - 在 C# 中 Decimal 和 decimal 不同吗?

python - 在 Python 中使用 7.0 或 float(7) 是否计算量较小?

ios - RestKit如何处理身份验证失败

ruby-on-rails - 如果ActiveRecord::RecordNotUnique error exists则重定向

haskell - 如何确保 Data.Vector 的分摊 O(n) 级联?

windows - cabal 安装 glib 出错

javascript - 在指令中使用scope.$watch时出错