我对Haskell和snap相当陌生,我正在为一个使用Snap的小型网络论坛完成我自己的项目。我遇到的问题是理解冲突以及如何解决下面的代码。
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 "/"给出一个类型不匹配错误如下:
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;
.... }任何消除混乱的建议都会很感激,我一直在寻找一些方法来解开可能,只是检索字节串,但没有成功。
非常感谢!
发布于 2013-07-29 18:43:20
Just是Maybe a类型的构造器。我敢肯定,getParam返回Snap Maybe Bytestring,所以bs是Maybe Bytestring类型的。当你说Just bs时,你就会有Maybe (Maybe Bytestring),这显然是你不想要的。您正在寻找fromJust :: Maybe a -> a,但是这个函数很危险,因为您还没有检查getParam是否成功,并且在html页面上有一个带有该名称的输入。
您应该做的是用例或>>=。
有点像
bs <- getParam "categoryName"
case bs of
Nothing -> writeBS "failed"
Just b -> do
let unpacked = B.unpack b
-- ... Do more stuff编辑
这取决于你想做什么。绑定是有用的,liftM、lifM2、liftM3等也是有用的。
在您的情况下,您可能需要liftM2。我不知道你喜欢什么类型,但我会举一个很简单的例子。如果你有这两个字节字符串,你可以这样做。
bs1 <- getParam "one"
bs2 <- getParam "two"
case (liftM2 append bs1 bs2) of
Nothing -> writeBS "Failed"
Just b -> writeBS b发布于 2013-08-12 18:55:45
从Maybe a类型提取值的一种很好的方法是从Data.Maybe模块中使用fromMaybe函数。如果在Nothing值的情况下,Maybe中有一个默认值可以使用,这是非常有用的。
我将在IO monad中给出一个示例,而不是一些Snap monad,以避免引入Snap库使演示代码工作,但只要处理程序与getParam操作处于相同的单元组中,它的工作方式就应该是相同的(除了类型签名更改外)。
{-# 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因为getParam1和getParam2是IO (Maybe ByteString),所以我们知道我们需要使用一元操作来获得内部的Maybe ByteString值。
通过查看>>=的类型签名(即m a -> (a -> m b) -> m b ),我们可以将类型a设置为Maybe ByteString,类型b设置为IO ByteString,这意味着我们希望使用这些特定类型应用绑定:
-- (Type of getParam1 >>= Type of our function to supply) -> Desired type
IO (Maybe ByteString) -> (Maybe ByteString -> IO ByteString) -> IO ByteString考虑到这一点,我们可以查看fromMaybe的类型
fromMaybe :: a -> Maybe a -> a我们可以使用默认的fromMaybe部分应用ByteString,并获得:
fromMaybe "No value" :: Maybe ByteString -> ByteString现在我们用return组合这个函数,将ByteString放回IO中。
return . fromMaybe "No value" :: Maybe ByteString -> IO ByteString这是我们需要对>>=的结果使用getParam1的类型。
由于我们位于do monad中的IO块中,因此可以使用<-绑定箭头语法提取ByteString以供进一步使用:
str1 <- getParam1 >>= return . fromMaybe "No value"此时,您可以在ByteString块中使用str1中的纯do。
希望你觉得这个解释有帮助!
https://stackoverflow.com/questions/17931442
复制相似问题