私はf(n)
それが返す関数のグラフを持っています
5 if n = 0
2 if n = 1
-4 if n = 2
1 if n = 3
9 if n = 4
8 if n = 5
9 if n = 6
0 otherwise
そして、ペアを持つ1つのリストを持つグラフを表す関数を書きたかったのです。
type Nat0 = Int
type Z = Int
type List = [Z]
type Graph = [(Nat0,Z)]
list_to_graph :: List -> Graph
list_to_graph x = list_to_graph' ([0..(length x)-1 ]) (x)
list_to_graph' :: [Int] -> List -> Graph
list_to_graph' (x:xs) (y:ys) = [(x, y)] ++ list_to_graph' (xs) (ys)
list_to_graph' [] [] = []
そして、それは私がここでしたことです。リストを渡す[5,2,-4,1,9,8,9]
戻ります
*Main> list_to_graph [5,2,-4,1,9,8,9]
[(0,5),(1,2),(2,-4),(3,1),(4,9),(5,8),(6,9)]
そしてこれが反対を行う関数です:
graph_to_list :: Graph -> List
graph_to_list (x:xs) = [snd (x)] ++ graph_to_list(xs)
graph_to_list []= []
グラフを渡す場所 [(0,5),(1,2),(2,-4),(3,1),(4,9),(5,8),(6,9)]
*Main> graph_to_list [(0,5),(1,2),(2,-4),(3,1),(4,9),(5,8),(6,9)]
[5,2,-4,1,9,8,9]
質問:
私が理解していないのは、次のようなものを書く方法です。
type Function = (Nat0 -> Z)
function_to_list :: Function -> List
または
list_to_function :: List -> Function
またはグラフについても同じ
function_to_graph :: Function -> Graph
graph_to_function :: Graph -> Function
このリンクで高階関数を読みましたが、これが実際にどのように機能するのか理解できないようです。
function_to_list
この表記(Nat0 -> Z)
(実際にはInt -> Int
)を持つ関数を渡す必要があり、List
with [Z]
(これは[Int]
)を返す必要があると思います。しかし、どうすればそれを行うことができますか?それは同じ関数をそれ自体に渡すようなものですか?
さらに紛らわしいのは、list_to_function
ここで何が結果になるのかということです。
誰かが私の例のいくつかで高階関数を説明してくれたら、本当にありがたいです!
編集:
ここでより明確にするために、私が達成したいことは次のとおりです。
(list_to_graph . graph_to_list) = λ x. x
(graph_to_list . list_to_graph) = λ x. x
上に示したように、リストを渡すlist_to_graph
とグラフが返され、graph_to_list
反対になります
(list_to_function . function_to_list) = λ x. x
(function_to_list . list_to_function) = λ x. x
他の2つの関数でやりたいことと同じです。asに適用function_to_list
しlist_to_function
てfunction_to_list
aを返し、List
それをlist_to_function
受け入れるList
と、リストから要素を取り出して適用する関数を返す必要があり、それに適用すると。Function
が返されますZ
。
私が今までに理解したこと:
function_to_list :: Function-> List
function_to_list f = [f(x) | x <- [0..6]]
function :: Function
function n
| n == 0 = 5
| n == 1 = 2
| n == 2 = (-4)
| n == 3 = 1
| n == 4 = 9
| n == 5 = 8
| n == 6 = 9
| otherwise = 0
以下の答えが示唆するように。
*Main> function_to_list function
[5,2,-4,1,9,8,9]
私がしたいのfunction :: Function
は私の中でこれを作ることですlist_to_function
だからあなたは取得しようとしています
list_to_function :: List -> Function
正しい?Graph
代わりにやってみましょう、それは本質に近づくでしょう。それを書き始めましょう。
graph_to_function gph = _ -- something of type Function
したがって、タイプの何かFunction
、つまり、を構築したいと思いNat0 -> Z
ます。それを行う最も退屈な方法は、ラムダを使用することです。
graph_to_function gph = \n -> _ -- something of type Z
グレートは、今、私たちは持っているGraph
と呼ばれるgph
とNat0
呼ばれるn
、と私たちは作りたいですZ
。ここでは、リストでを検索できn
ます。これを行うにはいくつかの方法があります。これが1つです。
graph_to_function gph = \n -> head ([ y | (x,y) <- gph, x == n ] ++ [0])
++ [0]
リスト内包表記が空になった場合、つまりn
グラフのドメインで見つからなかった場合に備えて、最後に付けました。完了!
面白いことに、Haskellの関数はデフォルトでカレーされているので
f x y z = ...
f = \x -> \y -> \z -> ...
同等です。つまり、これはgraph_to_function
2つの引数の関数とまったく同じです。したがってn
、定義の左側に移動できます。
graph_to_function :: Graph -> Function
graph_to_function gph n = head ([ y | (x,y) <- gph, x == n ] ++ [0])
署名に1つの引数だけが方程式の2つの引数であるのは少し奇妙に見えますが、慣れると実際に見られるものです。
お役に立てれば!
この記事はインターネットから収集されたものであり、転載の際にはソースを示してください。
侵害の場合は、連絡してください[email protected]
コメントを追加