0

Haskellでグローバル変数を使用することは嫌われていると私は確信しているので。とにかく次のことを達成できるのだろうか?

-- list has elements that are odd
listHasOdd :: [Integer] -> Bool
-- list has elements that are even
listHasEven :: [Integer] -> Bool
--list has a length > 5
longList :: [Integer] -> Bool

-- Maps the function to a [Bool]
-- This function cannot be modified to fix the problem.
checkList :: [Integer] -> [Bool]
checkList xs = map (\ y -> y xs) listChecker
where listChecker = [listHasOdd, listHasEven, longList]

とにかく、そのうちの1つだけがtrueを返すようにすることができますか?

たとえば、[1,2,3,5]の場合、listHasOddだけが[True、False、False]であるTrueを返すようにします。(上から下に評価)。

別の例、[2,4,6,8,10,12,14]の場合、戻り値は[False、True、False]である必要があります。

つまり、checkList [1,2,3,5]は[True、False、False]を返し、checkList [2,4,6,8,10,12,14]は[False、True、False]を返します。

**最後の関数は到達不能であるため、私の例では常にFalseになります。

前のものがそうであるかどうかを確認するためにifステートメントを実行できることは知っていますが、それはTrueかなりばかげた考えのようです。それとも実際にそれを行う方法ですか?(Haskellが前の関数の結果を「記憶」していることを考慮すると)

4

2 に答える 2

3

その要点はわかりませんが

foldr foo [] $ map ($ xs) [listHasOdd, listHasEven, longList]
  where
    foo True zs = True : map (const False) zs
    foo False zs = False : zs

目的の結果が生成され、関数の1つが返されるまでTrue(または関数のリストの最後に到達するまで)のみ関数が評価されます。

于 2013-03-26T19:00:37.780 に答える
2

これは私が思いつくことができる最高です。たとえば、ポーカーハンドで起こりうる結果の数を処理することは、比較的簡単に一般化できます。

data Outcome
    = ListHasOdd
    | ListHasEven
    | LongList
    | Nope
  deriving Eq

outcomeFromList :: [Integer] -> Outcome
outcomeFromList xs
    | any odd xs    = ListHasOdd
    | any even xs   = ListHasEven
    | 5 < length xs = LongList
    | otherwise     = Nope

listHasOdd = (ListHasOdd ==) . outcomeFromList
listHasEven = (ListHasEven ==) . outcomeFromList
longList = (LongList ==) . outcomeFromList

しかし、これでもばかげています。を生成する代わりに、直接[Bool]使用しないのはなぜですか?Outcome


編集:または、関数の意味に注意を払うことができます。

listHasOdd xs = any odd xs

listHasEven [] = False
listHasEven xs = all even xs
-- if not all of them are even, then at least one must be odd,
-- and `listHasOdd` would give `True`

longList _ = False
-- if the list has at least 5 elements,
-- then either the list has at least one odd element
-- (and `listHasOdd` would give `True`)
-- or the list has at least five even elements
-- (and `listHasEven` would give `True`)
于 2013-03-26T19:18:11.247 に答える