その正確な型署名ではありません。たとえば、を選択type b = Double->Double
して関数[b]->b
がfoldr (.) id
である場合、ポリモーフィック関数はそこで生成された値を使用してペアから選択するq
ことはできませんが、選択の手段を促進/解除するのではなく、特定のタイプのsigを探すと問題を誤解していると思います要素からペアへ。
生の選択問題を解決する
元の関数を使用してリストから要素を選択するだけの場合は、代わりに2つから選択する方法をHaskellに指示できます。
このソリューションは、ヘルパー関数を使用して、元のリストまたはフォールバック要素からの選択を強制するという意味で安全です。b -> b -> Bool
ここで、True
は、最初の引数を優先することを示します。
これを使用して、ペアから選択できます。
selectPair :: (a -> a -> Bool) -> (a,c) -> (a,c) -> (a,c)
selectPair f (a,c) (a',c')
| f a a' = (a,c)
| otherwise = (a',c')
次に、折りたたんでリストから選択します。
selectList :: (a -> a -> Bool) -> (a,c) -> [(a,c)] -> (a,c)
selectList f = foldr (selectPair f)
これはタイプのインスタンスを必要としないことに注意してa
ください。したがって、一般的な設定で必要になる場合があります。
最大の問題を解決する
もちろん、インスタンスからの(b -> b -> Bool)
ように感じます。例では、最大値を提案する関数を使用しましたが、Ordインスタンスがある場合は、インポートを使用して実行するのが最も簡単です。>
Ord
Data.List
Data.Function
safePairMaximum :: Ord b => (a, b) -> [(a, b)] -> (a, b)
safePairMaximum m bs = maximumBy (compare `on` snd) $ m:bs
これは、 hammarのソリューションの一部のより基本的でクールではないバージョンです。
たぶんあなたは立ち往生しています-[b]->bですが、bには平等があります
これは、あなたが述べた問題を解決しながら、私が賢明だと思う型注釈にできるだけ近づきます。選択関数を使用すること::[b]->b
が重要な場合は、少なくともEq
コンテキストが必要になります。
chooseLike :: Eq b => (a, b) -> ([b] -> b) -> ([(a, b)] -> (a, b))
chooseLike m selectb pairs = let wanted = selectb $ map snd pairs in
case filter ((==wanted).snd) pairs of
[] -> m
(p:_) -> p
(もちろん、Eq
コンテキストを(b -> b -> Bool)
引数に置き換えることができます。今回は平等を示します。)
これは理想的ではありません。[b]
リストを個別にリストに移動するため[(a,b)]
、非効率的です。
結論
あなたが指定したタイプの便利な機能はないと思いますが、あなたが述べた問題を解決するにはさまざまな方法があります。興味深い質問でした、ありがとう。