1

リストから単一の要素を返す関数を構築しようとしています。リストはMaybe (Int,[Int])tupel の一部です。

リストに要素が含まれていない場合は、エラーを返したいです。リストに含まれる要素が 1 つだけの場合、その要素を Monad として返します。リストに複数の要素が含まれている場合は、エラーを返したいです。

私は少し迷っており、このかなり単純なことを機能させる方法がわかりません。これが私がこれまでに持っているものです:

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

どんな助けでも大歓迎です!

4

2 に答える 2

2

私はあなたの仕様から翻訳します:

リストに要素が含まれていない場合は、エラーを返したいです。

f [] = mzero

リストに含まれる要素が 1 つだけの場合、その要素を Monad として返します。

f [x] = return x

リストに複数の要素が含まれている場合は、エラーを返したいです。

f (_:_:_) = mzero

したがって、すべてをまとめると、次のようになります。

singleElemOnly :: (MonadPlus m) => [a] -> m a
singleElemOnly []  = mzero
singleElemOnly [x] = return x
singleElemOnly _   = mzero
       -- a _ catches everything else, no need to write the exact pattern

または、もっと簡単に言えば、3 番目のケースには最初のケースが含まれているためです。

singleElemOnly :: (MonadPlus m) => [a] -> m a
singleElemOnly [x] = return x
singleElemOnly _   = mzero
于 2015-01-12T20:05:22.487 に答える
1

まず、フーグルはあなたの友達です。署名を調べて、getFirstis just fstgetSecondis snd、および の実装をgetValueとして記述できることを見つけることができますfromMaybe false

エラーメッセージに関してvalueは、タイプ(Integral i) => Maybe i(または近いもの、現在コンパイラを持っていません)を持っています。これは、singleElemOnly返される可能性のある値の1つです。しかし、署名は、呼び出し元が望むものを(MonadPlus m) => [a] -> m a返さなければならないと述べています。 MonadPlus

同様に、これを GHCi で実行している場合、 の型はtest2デフォルトで になりますが、任意のMaybe (Integer, [Integer])型を返すことがsingleElemOnlyできなければなりません。 Integral

于 2015-01-12T19:44:53.970 に答える