[英]How would I write cycle as a lambda function?
只是為了好玩,這是我自己的cycle
版本:
myCycle :: [a] -> [a]
myCycle xs = xs ++ myCycle xs
右側是指函數名稱myCycle
和參數xs
。
是否可以在不提及myCycle
或xs
情況下實現myCycle
?
myCycle = magicLambdaFunction
是否可以在不提及
myCycle
或xs
情況下實現myCycle
?
答案是肯定而不是(不一定按順序)。
其他人提到了定點組合器。 如果你有一個定點組合器fix :: (a -> a) -> a
,那么正如你在對Pubby的答案的評論中提到的那樣,你可以編寫myCycle = fix . (++)
myCycle = fix . (++)
。
但fix
的標准定義是這樣的:
fix :: (a -> a) -> a
fix f = let r = f r in r
-- or alternatively, but less efficient:
fix' f = f (fix' f)
請注意, fix
的定義涉及在其定義的右側提及左側變量(第一個定義中的r
,第二個定義中的“ fix'
)。 所以到目前為止我們真正做的就是把問題推到了fix
。
有趣的是,Haskell基於一個類型化的lambda演算,並且出於技術上的原因,大多數類型的lambda演算被設計成使得它們不能 “原生地”表達固定點組合。 如果您在基礎演算的“頂部”添加一些允許計算固定點的額外功能,這些語言只會變成圖靈完備。 例如,其中任何一個都可以:
fix
作為基元添加到微積分中。 fix
另一種方式)。 由於許多原因,這是一種有用的模塊化類型 - 一種是沒有固定點的lambda演算也是邏輯的一致證明系統,另一種可以證明在許多這樣的系統中無需fix
程序可以終止。
編輯:這是用遞歸類型編寫的fix
。 現在fix
本身的定義不是遞歸的,但Rec
類型的定義是:
-- | The 'Rec' type is an isomorphism between @Rec a@ and @Rec a -> a@:
--
-- > In :: (Rec a -> a) -> Rec a
-- > out :: Rec a -> (Rec a -> a)
--
-- In simpler words:
--
-- 1. Haskell's type system doesn't allow a function to be applied to itself.
--
-- 2. @Rec a@ is the type of things that can be turned into a function that
-- takes @Rec a@ arguments.
--
-- 3. If you have @foo :: Rec a@, you can apply @foo@ to itself by doing
-- @out foo foo :: a@. And if you have @bar :: Rec a -> a@, you can do
-- @bar (In bar)@.
--
newtype Rec a = In { out :: Rec a -> a }
-- | This version of 'fix' is just the Y combinator, but using the 'Rec'
-- type to get around Haskell's prohibition on self-application (see the
-- expression @out x x@, which is @x@ applied to itself):
fix :: (a -> a) -> a
fix f = (\x -> f (out x x)) (In (\x -> f (out x x)))
我認為這有效:
myCycle = \xs -> fix (xs ++)
http://en.wikipedia.org/wiki/Fixed-point_combinator
在支持匿名函數的編程語言中,定點組合器允許定義和使用匿名遞歸函數,即不必將這些函數綁定到標識符。 在此設置中,定點組合器的使用有時稱為匿名遞歸。
為了好玩,這是另一回事:
let f = foldr (++) [] . repeat
要么
let f = foldr1 (++) . repeat
沒有人指出修復解決方案的“明顯”版本。 我們的想法是將命名的遞歸調用轉換為參數。
let realMyCycle = fix (\myCycle xs -> xs ++ myCycle xs)
這種“遞回域名”引入招是相當多的東西let in
確實在Haskell。 唯一的區別是使用內置構造更直接,並且可能更好地實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.