2

次のコードを検討してください。

type Graph = (Char, Function) 
type Function = Char -> Int 
doThingsWithGraph :: Graph -> String
func :: Function 
graph :: Graph

main = do  x <- getChar
           y <- getChar
           let graph = (x, func)
           putStrLn $ doThingsWithGraph graph

の実装はdoThingsWithGraph今のところ問題ありません。ここでの問題は、funcの出力がユーザーから取得した2番目の文字にも依存することですが、それを渡す方法がわかりません。funcはサードパーティで実装されており、型を変更できないため、引数として渡すことができません。したがって、 haskell にグローバル変数yがあり、その 1 つである場合、funcの実装は次のようになります。

func char 
       |isDigit char = digitToInt char + digitToInt y
       |otherwise    = digitToInt y

これは明らかに機能しません。なぜなら、それがfunc何でyあるかわからないからです。yなんらかの形で通知する必要がある値です(これfuncは、の 2 行目でユーザーから取得しているものですmain)。変更できないデータ型 (大規模なフレームワークの一部) と一致しないため、getLine内部で行うことはできません。func何か案は?たぶん、いくつかのヘルパー関数が関数型の関数を置き換えfunclet graph = (x, func)返すことができますか? これは単なる推測です..

4

2 に答える 2

5

ユーザー生成funcは、次のような関数を実装するだけで、最初の引数として入力から2番目の文字を与えるという約束でChar -> Function、生の代わりにそれを渡すことができます。Function

実際、これはグローバルを持たない言語では非常に自然なことです: 関数入力で必要なすべての情報を記述しなければなりません。それ以外は機能しません。

あなたはで終わるでしょう

doThingsWithGraph (x, makeFunc y)

それが面倒なときは、 Reader モナドが役に立ちます。

于 2013-10-26T19:22:33.697 に答える
1

func「サードパーティによって実装されている」の意味がよくわかりません。「私がこのように使用できるように、サードパーティがそのような を実装できるようにしてほしい」ということfuncですか?

もしそうなら、

func :: Char -> Function
func y char 
       |isDigit char = digitToInt char + digitToInt y
       |otherwise    = digitToInt y

仕事をしますか?これは、J.エイブラハムソンが示唆していることでもあると思います。

于 2013-10-26T19:31:23.673 に答える