Abr*_*m P 1 error-handling haskell types type-systems maybe
假设我想解析一个环境变量,并在缺席的情况下默认为localhost,使用https://hackage.haskell.org/package/network-2.3/docs/Network-URI.html
我可以写一个这样的函数:
parseRabbitURI :: Text -> Maybe URI.URI
parseRabbitURI "" = URI.parseURI "amqp://guest:guest@127.0.0.1/"
parseRabbitURI uri = (URI.parseURI . toS) uri
Run Code Online (Sandbox Code Playgroud)
这很好用.现在让我们说我想处理错误.我注意到parseURI返回一个Maybe表面上我只需要模式匹配.所以我创建了一个自定义错误:
data CustomError = MyCustomError Text deriving(Show)
Run Code Online (Sandbox Code Playgroud)
我创建了一个辅助函数:
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
Run Code Online (Sandbox Code Playgroud)
最后,我修改了我的初始函数:
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
Run Code Online (Sandbox Code Playgroud)
这无法编译:
• 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
Run Code Online (Sandbox Code Playgroud)
| 23 | parseRabbitURI uri =(URI.parseURI.toS)uri >> = parsedExtractor uri |
而对于我的生活,我无法弄清楚为什么.如果初始实现返回一个Maybe,为什么它转换为unwrapper URI.URI,然后我无法传递?
至关重要的是,当我将模式更改parsedExtractor为期望字符串时,它也无法使用反向消息进行编译(
Couldn't match expected type ‘URI.URI’
with actual type ‘Maybe URI.URI’
Run Code Online (Sandbox Code Playgroud)
我觉得我必须遗漏一些完全基本的东西.这里发生了什么?
而对于我的生活,我无法弄清楚为什么.如果初始实现返回一个Maybe,为什么它转换为unwrapper URI.URI,然后我无法传递?
要引用的定义>>=从Control.Monad,它的类型是signture:
(>>=) :: m a -> (a -> m b) -> m b
Run Code Online (Sandbox Code Playgroud)
现在,与表达式进行比较:
(URI.parseURI . toS) uri >>= parsedExtractor uri
Run Code Online (Sandbox Code Playgroud)
我们有:
m a ~ (URI.parseURI . toS) uri
(a -> m b) ~ parsedExtractor uri
Run Code Online (Sandbox Code Playgroud)
因为(URI.parseURI . toS) uri返回类型Maybe URI.URI并且Maybe是一个实例Monad,所以
m a ~ Maybe URI.URI
Run Code Online (Sandbox Code Playgroud)
和
(a -> m b) ~ (URI.URI -> m b)
Run Code Online (Sandbox Code Playgroud)
并且m b可以被推测为m (URI.URI),因此预期的函数(即parsedExtractor uri)>>=具有如下类型:
(URI.URI -> m (URI.URI))
Run Code Online (Sandbox Code Playgroud)
但事实并非如此.
| 归档时间: |
|
| 查看次数: |
92 次 |
| 最近记录: |