0

私は中級者ですが、haskell の初心者に過ぎません。これが私の問題です:

連想二項演算があるとします(>>=)pそのような多変量関数はありp (>>=) h g f e = h >>= g >>= f >>= eますか?

この質問は、二項演算が同じタイプの入力を受け取る場合に可能であると述べているため、この質問をしています。これは一般化できるのだろうか。

EDIT-1: http://okmij.org/ftp/Haskell/vararg-fn.lhs (可変型引数の可変数のセクション) のコードを変更しようとしていますが、ほとんど進展がありません。

EDIT-2: コードを少し単純化します。

{-# LANGUAGE FunctionalDependencies, FlexibleInstances #-}


module Main where


class Lfold f a b | b -> a where 
  lfold :: (a -> (f a) -> (f a)) -> (f a) -> a -> b

instance Lfold f a (f a) where
  lfold op rid x = op x rid

instance Lfold f a b => Lfold f a (a -> b) where
  lfold op rid x y = lfold op (op x rid) y


test :: [String]
test = lfold (:) [] "a" "b" "c"

main :: IO ()
main = putStrLn $ show test
4

2 に答える 2

1

事前に取得する引数の数を知る必要があるため、できません (少なくとも、簡単ではありません)。Haskell のすべての関数は自動的にカリー化されるため、すべての関数は厳密に 1 つの引数を取り、1 つの値を返します。単純な二項演算子でさえ、1 つの引数 (最初のオペランド) を取り、1 つの引数 (2 番目のオペランド) を取り、結果を返す関数を返します。あれは、

a + b == (+) a b
      == ((+) a) b

虚数関数pが最初の引数から、他にいくつの引数が与えられるかを知る方法はありません。つまり、型は何であるべきpか?

p :: (a -> a -> a) -> a                -- zero arguments?
p :: (a -> a -> a) -> a -> a           -- one argument?
p :: (a -> a -> a) -> a -> a -> a      -- two arguments?
p :: (a -> a -> a) -> a -> a -> a -> a -- three arguments?

代わりに、操作とオペランドのリストを受け取る折り畳みを使用するのが最善です。

foldr (+) 0 [h, g, f, e] == h + g + f + e + 0  -- explicit first argument of 0
foldr1 (+) [h, g, f, e] == h + g + f + e -- assumes a list of at least one value

「簡単ではない」という言葉の意味を理解するにprintfは、Text.Printfモジュールの の実装を見てください。これも良い例ではありません。最初の引数には、2 項演算だけでは得られない情報 (書式文字列内のプレースホルダーの数) が含まれているからです。

于 2016-09-17T15:43:12.960 に答える