その正確な型署名ではありません。たとえば、を選択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インスタンスがある場合は、インポートを使用して実行するのが最も簡単です。>OrdData.ListData.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)]、非効率的です。
結論
あなたが指定したタイプの便利な機能はないと思いますが、あなたが述べた問題を解決するにはさまざまな方法があります。興味深い質問でした、ありがとう。