4

私はまだプログラミングに非常に慣れていないので、Haskellの構文に苦労しています。何を実装したいのかはある程度わかっていますが、それを行う方法がよくわからないので、ここに尋ねに来ました。

だから私が持っているのは、3つの異なる関数によって定義された特定の順序ではない数字の「山」です。この例は次のようになります。

lowestnumber = 4
highestnumber 5 = True
highestnumber _ = False
above 4 = 11
above 11 = 18
above 18 = 2
above 2  = 3
above 3  = 5
above 5  = error "highest Number"
above _ = error "Not part of the pile"

ここで、特定の数がこのパイルの一部であるかどうかをチェックする関数と、入力変数なしでリストのすべての要素を合計する別の関数 "sum' = " を書きたいと思います。まず、リストを定義し、リストコマンドを使用して合計し、elemそのリストに何かが含まれているかどうかを確認することでこれらの問題を解決しましたが、リストを使用せずに解決することになっています。

したがって、これを解決する方法についてのアイデアはありますが、数え切れないほどのエラーを受けずに実際に記述する方法はわかりません。私がチェック機能のために試したことのいくつかの例:

check x = if above x /= error "Not part of the stack" || lowestnumber == x then True else False

このように「_」を使用してチェックも試みましたが、どちらも機能しません。

check x if above x == _ || lowestnumber == x then True else False

sum 関数の私のアイデアは次のとおりです。

sum' = lowestnumber + above lowestnumber + above (above lowestnumber) + above (above (above lowestnumber))

または次のようなもの

sum' = lowestnumber + (above sum') 

私が理解していることは

などですが、どうやら再帰を使用してこれを実装する方法がわかりませんでした。

うまくいけば、この質問はあまりにも愚かではありません! あなたが私を助けてくれることを願っています:)

編集:わかりました、これらは私の3つの機能問題の解決策です

sumup' a b 
           |highestNumber a == True = a+b 
           |otherwise = sumup' (above a) (a+b)

sumup = sumup' lowestNumber 0



check' a b 
            |a == b = True
            |True == highestNumber a && a==b = True
            |True == highestNumber a && a/=b = False
            |check' (above a) (b) == True = True
            |otherwise = False

check b = check' (lowestNumber) (b)



above' :: Integer -> Integer -> Bool
above' x y
            | check x == False = False
            | check y == False = False
            | highestNumber y == True = False
            | highestNumber x == True = True
            | x==y = True
            | above' x (above y) == True = True
            | otherwise = False
4

5 に答える 5

3

Haskell のさまざまな高階関数は、 などのさまざまな再帰 (およびコアカーション†</sup>) パターンをキャプチャします。iteratefoldrunfoldr

ここで を使用できます。ここで、 から始めて、保持されるまで繰り返し適用した結果until :: (a -> Bool) -> (a -> a) -> a -> aが得られます。until p f xfpx

sumPile = snd $ 
    until (highestnumber . fst) 
          (\(a,b)->(above a, b + above a)) 
          (lowestnumber,   lowestnumber)

また、

inThePile p = p==until (\n-> highestnumber n || n==p) above lowestnumber

†</sup> 基本的に、アキュムレータを使用した再帰は、開始ケースから進む途中で結果を構築しますが、通常の再帰は、基本ケースから戻る途中で結果を構築します。

于 2013-05-01T13:10:23.467 に答える
2

最初に、リストを定義し、リストコマンドを使用して合計してそのリストの「要素」であるかどうかを確認することでこれらの問題を解決しましたが、リストを使用せずに解決することになっています。

これは、次のように elem を展開することで解決できます。

x `elem` [1,2,3]

と同じです

x == 1 || x == 2 || x == 3

そして、あなたがそれをしている間

sum' = 4 + 11 + 18 + 2 + 4  + 5

次のようなものを使用して、すべての要素のリストを作成することもできます

elements = takeUntil highestnumber (iterate above lowestnumber)

takeUntil p xs = foldr (\x r -> if p x then [x] else x:r) [] xs

これは、定数を使用せずにチェックと合計の関数を記述できる唯一の方法です。


takeWhile (not . highestnumber)最大数を見逃すので使用できません。そのためtakeUntil、出力に中断要素を含めるには、このように定義する必要があります。

于 2013-05-01T10:24:38.903 に答える