首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >类型不匹配ByteString /可能ByteString

类型不匹配ByteString /可能ByteString
EN

Stack Overflow用户
提问于 2013-07-29 18:25:41
回答 2查看 320关注 0票数 0

我对Haskell和snap相当陌生,我正在为一个使用Snap的小型网络论坛完成我自己的项目。我遇到的问题是理解冲突以及如何解决下面的代码。

代码语言:javascript
复制
handleCategoryAdd :: H ()
handleCategoryAdd = method POST (withLoggedInUser go)
  where
    go user = do
      bs <- getParam "categoryName"
      cN <- B.unpack $ Just bs
      cD <- getParam "categoryDesc"
      cT <- getCurrentTime
      return (Db.saveCategory (Db.Category 1 cN cT "1" ))
      redirect "/"

给出一个类型不匹配错误如下:

代码语言:javascript
复制
src\Site.hs:118:22:
    Couldn't match expected type `ByteString'
                with actual type `Maybe ByteString'
    In the first argument of `unpack', namely `bs'
    In a stmt of a 'do' block: cN <- unpack bs
    In the expression:
      do { bs <- getParam "categoryName";
           cN <- unpack bs;
           cD <- getParam "categoryDesc";
           cT <- getCurrentTime;
           .... }

任何消除混乱的建议都会很感激,我一直在寻找一些方法来解开可能,只是检索字节串,但没有成功。

非常感谢!

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2013-07-29 18:43:20

JustMaybe a类型的构造器。我敢肯定,getParam返回Snap Maybe Bytestring,所以bsMaybe Bytestring类型的。当你说Just bs时,你就会有Maybe (Maybe Bytestring),这显然是你不想要的。您正在寻找fromJust :: Maybe a -> a,但是这个函数很危险,因为您还没有检查getParam是否成功,并且在html页面上有一个带有该名称的输入。

您应该做的是用例或>>=

有点像

代码语言:javascript
复制
bs <- getParam "categoryName"
case bs of
   Nothing -> writeBS "failed"
   Just b  -> do
      let unpacked = B.unpack b
      -- ... Do more stuff

编辑

这取决于你想做什么。绑定是有用的,liftMlifM2liftM3等也是有用的。

在您的情况下,您可能需要liftM2。我不知道你喜欢什么类型,但我会举一个很简单的例子。如果你有这两个字节字符串,你可以这样做。

代码语言:javascript
复制
bs1 <- getParam "one"
bs2 <- getParam "two"

case (liftM2 append bs1 bs2) of
   Nothing -> writeBS "Failed"
   Just b  -> writeBS b
票数 3
EN

Stack Overflow用户

发布于 2013-08-12 18:55:45

Maybe a类型提取值的一种很好的方法是从Data.Maybe模块中使用fromMaybe函数。如果在Nothing值的情况下,Maybe中有一个默认值可以使用,这是非常有用的。

我将在IO monad中给出一个示例,而不是一些Snap monad,以避免引入Snap库使演示代码工作,但只要处理程序与getParam操作处于相同的单元组中,它的工作方式就应该是相同的(除了类型签名更改外)。

代码语言:javascript
复制
{-# LANGUAGE OverloadedStrings #-}
import           Data.Maybe
import           Data.ByteString.Char8 (ByteString)
import qualified Data.ByteString.Char8 as B

getParam1, getParam2 :: IO (Maybe ByteString)
getParam1 = return $ Just "Hello"
getParam2 = return $ Nothing

main :: IO ()
main = do
   str1 <- getParam1 >>= return . fromMaybe "No value"
   str2 <- getParam2 >>= return . fromMaybe "No value"

   B.putStrLn str1
   B.putStrLn str2

因为getParam1getParam2IO (Maybe ByteString),所以我们知道我们需要使用一元操作来获得内部的Maybe ByteString值。

通过查看>>=的类型签名(即m a -> (a -> m b) -> m b ),我们可以将类型a设置为Maybe ByteString,类型b设置为IO ByteString,这意味着我们希望使用这些特定类型应用绑定:

代码语言:javascript
复制
-- (Type of getParam1 >>= Type of our function to supply)    -> Desired type 
IO (Maybe ByteString) -> (Maybe ByteString -> IO ByteString) -> IO ByteString

考虑到这一点,我们可以查看fromMaybe的类型

代码语言:javascript
复制
fromMaybe :: a -> Maybe a -> a

我们可以使用默认的fromMaybe部分应用ByteString,并获得:

代码语言:javascript
复制
fromMaybe "No value" :: Maybe ByteString -> ByteString

现在我们用return组合这个函数,将ByteString放回IO中。

代码语言:javascript
复制
return . fromMaybe "No value" :: Maybe ByteString -> IO ByteString

这是我们需要对>>=的结果使用getParam1的类型。

由于我们位于do monad中的IO块中,因此可以使用<-绑定箭头语法提取ByteString以供进一步使用:

代码语言:javascript
复制
str1 <- getParam1 >>= return . fromMaybe "No value"

此时,您可以在ByteString块中使用str1中的纯do

希望你觉得这个解释有帮助!

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/17931442

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档