2016-09-25 7 views
1

は、だから私は、カスタムデータ型を持つカスタムデータ型の最小値を検索し、のは次のように定義され、Structそれを呼びましょう:私は何をする必要があることはStruct内のすべての要素を通過することですハスケル:

data Struct = Struct [SubStruct] deriving (Read, Show) 
data SubStruct = SubStruct (Int, Int) deriving (Read, Show) 

fstに基づいて最小値を探し、sndに基づいて最小値を見つけます。それ、どうやったら出来るの? 具体的には、コード内の例に基づいて、

のように別のSubStructを取得したいとします。

現在、私はこのことによって開始:

import Data.List 
import Data.Function (on) 
import Data.List (sortBy) 

data Struct = Struct [SubStruct] deriving (Read, Show) 
data SubStruct = SubStruct (Int, Int) deriving (Read, Show ) 

struct s sx = Struct(s:sx) 

subStruct :: (Int, Int) -> SubStruct 
subStruct (x, y) = SubStruct (x, y) 

substructs = Struct $ [subStruct (0,1), subStruct (-2, 3), subStruct (4,-5)] 

results xs = sortBy (compare `on` fst) (substructs xs) 

をしかし、私はこのエラーを取得する:

Couldn't match expected type `t -> [(a, b)]' 
      with actual type `Struct' 
Relevant bindings include 
    xs :: t (bound at bbox.hs:15:9) 
    results :: t -> [(a, b)] (bound at file.hs:15:1) 
The function `substructs' is applied to one argument, 
but its type `Struct' has none 
In the second argument of `sortBy', namely `(substructs xs)' 
In the expression: sortBy (compare `on` fst) (substructs xs) 
+0

'substructs'が値であるが、それは機能(あなたが州にこの投稿を誤りであるかのようにあなたがそれを使用する - おそらくあなたが読んでくださいより密接に)。さらに、 'SortBy(' on \ 'fstと比較)'は 'SubStruct'のリストに適用される正しい型を持っていません - ' Ord a => [(a、b)] - > [(a、 b)]。 – user2407038

答えて

6

unzip機能を使用しない理由。我々は補助関数を定義する場合:これは二度リストを横断すること

getMin :: Struct -> SubStruct 
getMin (Struct l) = SubStruct (minimum xs, minimum ys) 
    where 
    (xs, ys) = unzip $ map unSubStruct l 

注:

unSubStruct :: SubStruct -> (Int, Int) 
unSubStruct (SubStruct p) = p 

次に、あなたが望む要素を返す関数は、のように記述することができます。

getMin :: Struct -> SubStruct 
getMin (Struct l) = 
    SubStruct $ foldr1 minPair $ map unSubStruct l 
    where 
    minPair (x0, y0) (x, y) = (min x0 x, min y0 y) 
+0

それは動作します。ありがとう! – Comforse

0

あなたは基本的にタプルのリストと同じであるSubStructのリストを、持っている:あなたはペアで動作し、独自のバージョンminimumを定義した場合ことを避けることができます。

だから、唯一の共通の機能を使用して一つの解決策は次のようになります。

result = SubStruct (min1, min2) where 
    min1 = minimum (map fst . list) 
    min2 = minimum (map snd . list) 
    list = case substructs of 
     Struct this -> map (\(SubStruct t) -> t) this 
+0

あなたの答えをありがとう。私は@ rednebの答えを今のところ印しましたが、より効率的に見えますが、おそらく私は間違っています:) – Comforse

+0

あなたは一番好きなものをマークすることができます、私は@rednebを羨望していません – Ingo