Note that there are some explanatory texts on larger screens.

plurals
  1. POI want to write a function which is similar to `flip` in Haskell to get rid of lambda expressions. But I can't deal with it's type
    primarykey
    data
    text
    <p>I want to write a Haskell function which acts like flip but is far more general and can make any parameter of a function be the last parameter. For convenience, we use <code>pull</code> to represent it.</p> <p>It is easy to write the following code:</p> <pre><code>Prelude&gt; :t flip --we just call this function a swap flip :: (a -&gt; b -&gt; c) -&gt; b -&gt; a -&gt; c Prelude&gt; :t (flip.) --we just call this function a swap (flip.) :: (a -&gt; a1 -&gt; b -&gt; c) -&gt; a -&gt; b -&gt; a1 -&gt; c Prelude&gt; :t ((flip.).) --we just call this function a swap ((flip.).) :: (a -&gt; a1 -&gt; a2 -&gt; b -&gt; c) -&gt; a -&gt; a1 -&gt; b -&gt; a2 -&gt; c Prelude&gt; :t (((flip.).).) --we just call this function a swap (((flip.).).) :: (a -&gt; a1 -&gt; a2 -&gt; a3 -&gt; b -&gt; c) -&gt; a -&gt; a1 -&gt; a2 -&gt; b -&gt; a3 -&gt; c </code></pre> <p>And we find that with more (.) applied to flip, it can swap arbitrary adjacent pair of parameters. And with the above results we can write:</p> <pre><code>Prelude&gt; :t flip flip :: (a -&gt; b -&gt; c) -&gt; b -&gt; a -&gt; c Prelude&gt; :t (flip.) . flip (flip.) . flip :: (a1 -&gt; a -&gt; b -&gt; c) -&gt; a -&gt; b -&gt; a1 -&gt; c Prelude&gt; :t ((flip.).) . (flip.) . flip ((flip.).) . (flip.) . flip :: (a2 -&gt; a -&gt; a1 -&gt; b -&gt; c) -&gt; a -&gt; a1 -&gt; b -&gt; a2 -&gt; c Prelude&gt; :t (((flip.).).) . ((flip.).) . (flip.) . flip (((flip.).).) . ((flip.).) . (flip.) . flip :: (a3 -&gt; a -&gt; a1 -&gt; a2 -&gt; b -&gt; c) -&gt; a -&gt; a1 -&gt; a2 -&gt; b -&gt; a3 -&gt; c </code></pre> <p>We can find that with more swaps composed, it can pull an arbitrary parameter to the last place. So we can get rid of lambda expressions in many cases. But the above express is very bloated.</p> <p>My main idea is to make a function <code>pull</code> to generalize the above functions. The <code>pull</code> acts roughly like bellow.</p> <pre><code>let f = undefined --For convenience, we let f be undefined. :t pull 0 (f::a-&gt;b-&gt;z) --the type variable z is not a function type. &gt;pull 0 (f::a-&gt;b-&gt;z) :: b-&gt;a-&gt;z --pull is just like flip for 0 and a function of this type. :t pull 0 (f::a-&gt;b-&gt;c-&gt;z) --the type variable z is not a function type. &gt;pull 0 (f::a-&gt;b-&gt;c-&gt;z) :: b-&gt;c-&gt;a-&gt;z :t pull 1 (f::a-&gt;b-&gt;c-&gt;z) --the type variable z is not a function type. &gt;pull 1 (f::a-&gt;b-&gt;c-&gt;z) :: a-&gt;c-&gt;b-&gt;z :t pull 1 (f::a-&gt;b-&gt;c-&gt;d-&gt;z) --the type variable z is not a function type. &gt;pull 1 (f::a-&gt;b-&gt;c-&gt;d-&gt;z) :: a-&gt;c-&gt;d-&gt;b-&gt;z :t pull 2 (f::a-&gt;b-&gt;c-&gt;d-&gt;z) --the type variable z is not a function type. &gt;pull 2 (f::a-&gt;b-&gt;c-&gt;d-&gt;z) :: a-&gt;b-&gt;d-&gt;c-&gt;z :t pull 2 (f::a-&gt;b-&gt;c-&gt;d-&gt;e-&gt;z) --the type variable z is not a function type. &gt;pull 2 (f::a-&gt;b-&gt;c-&gt;d-&gt;e-&gt;z) :: a-&gt;b-&gt;d-&gt;e-&gt;c-&gt;z </code></pre> <p>I tried many ways to do this. The naivest one is:</p> <pre><code>swap :: Word -&gt; a -&gt; a swap 0 = flip swap n = dot $ swap (n-1) </code></pre> <p>and ghc complained like bellow and I understand why:</p> <pre><code>-- Prelude&gt; :reload -- [1 of 1] Compiling Main ( ModifyArbitrayParameterOfAFunction.hs, interpreted ) -- -- ModifyArbitrayParameterOfAFunction.hs:4:21: -- Occurs check: cannot construct the infinite type: c0 = a1 -&gt; c0 -- Expected type: (a1 -&gt; c0) -&gt; c0 -- Actual type: (a1 -&gt; c0) -&gt; a1 -&gt; c0 -- In the return type of a call of `modify' -- Probable cause: `modify' is applied to too few arguments -- In the first argument of `(.)', namely `(modify (n - 1) modi)' -- In the expression: (modify (n - 1) modi) . f1 -- -- ModifyArbitrayParameterOfAFunction.hs:4:42: -- Occurs check: cannot construct the infinite type: c0 = a1 -&gt; c0 -- Expected type: a1 -&gt; a1 -&gt; c0 -- Actual type: a1 -&gt; c0 -- In the second argument of `(.)', namely `f1' -- In the expression: (modify (n - 1) modi) . f1 -- In an equation for `modify': -- modify n modi f1 = (modify (n - 1) modi) . f1 -- Failed, modules loaded: none. </code></pre> <p>Maybe my goal is just a wishful thinking, but considering Haskell's type system is even able to write lambda expressions, I dare to say there must be a way to do this.</p>
    singulars
    1. This table or related slice is empty.
    1. This table or related slice is empty.
    plurals
    1. This table or related slice is empty.
    1. This table or related slice is empty.
 

Querying!

 
Guidance

SQuiL has stopped working due to an internal error.

If you are curious you may find further information in the browser console, which is accessible through the devtools (F12).

Reload