【发布时间】:2015-01-12 19:32:45
【问题描述】:
我正在尝试构建一个函数,该函数将列表中的单个元素返回给我。该列表是Maybe (Int,[Int]) tupel 的一部分。
如果列表不包含任何元素,我想返回一个错误。 如果列表正好包含 1 个元素,我想将该元素作为 Monad 返回。 如果列表包含超过 1 个元素,我想返回一个错误。
我有点迷茫,不知道如何让这个相当简单的事情发挥作用。 这是我目前所拥有的:
import Control.Monad
test1 = Just (1,[2,3]) :: Maybe (Int,[Int])
test2 = Just (2,[1]) :: Maybe (Int,[Int])
test3 = Just (3,[]) :: Maybe (Int,[Int])
getValue :: Maybe Bool -> Bool
getValue (Just x) = x
getValue Nothing = False
singleElemOnly :: (MonadPlus m) => [a] -> m a
singleElemOnly x = let result = test2
value = fmap fst result
isEmpty = fmap null (fmap snd result)
in if (getValue isEmpty) then value else mzero
不幸的是,我在尝试编译时收到的错误消息对我这个初学者来说完全没有用..
Playground.hs:15:50:
Could not deduce (a ~ Int)
from the context (MonadPlus m)
bound by the type signature for
singleElemOnly :: MonadPlus m => [a] -> m a
at Playground.hs:11:19-45
`a' is a rigid type variable bound by
the type signature for singleElemOnly :: MonadPlus m => [a] -> m a
at Playground.hs:11:19
Expected type: m a
Actual type: Maybe Int
Relevant bindings include
x :: [a]
(bound at Playground.hs:12:16)
singleElemOnly :: [a] -> m a
(bound at Playground.hs:12:1)
In the expression: value
In the expression: if (getValue isEmpty) then value else mzero
Playground.hs:15:50:
Could not deduce (m ~ Maybe)
from the context (MonadPlus m)
bound by the type signature for
singleElemOnly :: MonadPlus m => [a] -> m a
at Playground.hs:11:19-45
`m' is a rigid type variable bound by
the type signature for singleElemOnly :: MonadPlus m => [a] -> m a
at Playground.hs:11:19
Expected type: m a
Actual type: Maybe Int
Relevant bindings include
singleElemOnly :: [a] -> m a
(bound at Playground.hs:12:1)
In the expression: value
In the expression: if (getValue isEmpty) then value else mzero
非常感谢任何帮助!
【问题讨论】:
-
错误信息是什么?始终发布您看到的编译器错误。
-
对不起,错误很长。我添加了它们并修复了示例。
-
将类型签名添加到
test1,...:可能您希望这些类型为Maybe (Int,[Int])或类似的类型。 GHC 为您选择了Integer而不是Int。修复此类型后,您现在可以看到您的函数singleElemOnly仅返回Int/Integer类型,而它的签名承诺它适用于任何类型a(不仅适用于Int)。这是 GHC 报告的类型错误。 -
此外,我不清楚你的最后一个函数应该做什么。你能编辑你的问题来解释你想要达到的目标吗?我目前的猜测类似于
f [] = mzero ; f (x:_) = return x,但很难说。 -
@chi 抱歉,我用最新的代码和错误更新了问题,并更好地解释了我想要实现的目标。