Does Scala have an operator similar to Haskell's `$`? - function

Does Scala have an operator similar to Haskell's $?
-- | Application operator. This operator is redundant, since ordinary
-- application #(f x)# means the same as #(f '$' x)#. However, '$' has
-- low, right-associative binding precedence, so it sometimes allows
-- parentheses to be omitted; for example:
--
-- > f $ g $ h x = f (g (h x))
--
-- It is also useful in higher-order situations, such as #'map' ('$' 0) xs#,
-- or #'Data.List.zipWith' ('$') fs xs#.
{-# INLINE ($) #-}
($) :: (a -> b) -> a -> b
f $ x = f x

Yes, it's written "apply"
fn apply arg
There's no standard punctuation operator for this, but it would be easy enough to add one via library pimping.
class RichFunction[-A,+B](fn: Function1[A, B]){ def $(a:A):B = fn(a)}
implicit def function2RichFunction[-A,+B](t: Function1[A, B]) = new RichFunction[A, B](t)
In general, while Scala code is much denser than Java, it's not quite as dense as Haskell. Thus, there's less payoff to creating operators like '$' and '.'

Related

How can I return a lambda with guards and double recursion?

I made this function in Python:
def calc(a): return lambda op: {
'+': lambda b: calc(a+b),
'-': lambda b: calc(a-b),
'=': a}[op]
So you can make a calculation like this:
calc(1)("+")(1)("+")(10)("-")(7)("=")
And the result will be 5.
I wanbt to make the same function in Haskell to learn about lambdas, but I am getting parse errors.
My code looks like this:
calc :: Int -> (String -> Int)
calc a = \ op
| op == "+" = \ b calc a+b
| op == "-" = \ b calc a+b
| op == "=" = a
main = calc 1 "+" 1 "+" 10 "-" 7 "="
There are numerous syntactical problems with the code you have posted. I won't address them here, though: you will discover them yourself after going through a basic Haskell tutorial. Instead I'll focus on a more fundamental problem with the project, which is that the types don't really work out. Then I'll show a different approach that gets you the same outcome, to show you it is possible in Haskell once you've learned more.
While it's fine in Python to sometimes return a function-of-int and sometimes an int, this isn't allowed in Haskell. GHC has to know at compile time what type will be returned; you can't make that decision at runtime based on whether a string is "=" or not. So you need a different type for the "keep calcing" argument than the "give me the answer" argument.
This is possible in Haskell, and in fact is a technique with a lot of applications, but it's maybe not the best place for a beginner to start. You are inventing continuations. You want calc 1 plus 1 plus 10 minus 7 equals to produce 5, for some definitions of the names used therein. Achieving this requires some advanced features of the Haskell language and some funny types1, which is why I say it is not for beginners. But, below is an implementation that meets this goal. I won't explain it in detail, because there is too much for you to learn first. Hopefully after some study of Haskell fundamentals, you can return to this interesting problem and understand my solution.
calc :: a -> (a -> r) -> r
calc x k = k x
equals :: a -> a
equals = id
lift2 :: (a -> a -> a) -> a -> a -> (a -> r) -> r
lift2 f x y = calc (f x y)
plus :: Num a => a -> a -> (a -> r) -> r
plus = lift2 (+)
minus :: Num a => a -> a -> (a -> r) -> r
minus = lift2 (-)
ghci> calc 1 plus 1 plus 10 minus 7 equals
5
1 Of course calc 1 plus 1 plus 10 minus 7 equals looks a lot like 1 + 1 + 10 - 7, which is trivially easy. The important difference here is that these are infix operators, so this is parsed as (((1 + 1) + 10) - 7), while the version you're trying to implement in Python, and my Haskell solution, are parsed like ((((((((calc 1) plus) 1) plus) 10) minus) 7) equals) - no sneaky infix operators, and calc is in control of all combinations.
chi's answer says you could do this with "convoluted type class machinery", like printf does. Here's how you'd do that:
{-# LANGUAGE ExtendedDefaultRules #-}
class CalcType r where
calc :: Integer -> String -> r
instance CalcType r => CalcType (Integer -> String -> r) where
calc a op
| op == "+" = \ b -> calc (a+b)
| op == "-" = \ b -> calc (a-b)
instance CalcType Integer where
calc a op
| op == "=" = a
result :: Integer
result = calc 1 "+" 1 "+" 10 "-" 7 "="
main :: IO ()
main = print result
If you wanted to make it safer, you could get rid of the partiality with Maybe or Either, like this:
{-# LANGUAGE ExtendedDefaultRules #-}
class CalcType r where
calcImpl :: Either String Integer -> String -> r
instance CalcType r => CalcType (Integer -> String -> r) where
calcImpl a op
| op == "+" = \ b -> calcImpl (fmap (+ b) a)
| op == "-" = \ b -> calcImpl (fmap (subtract b) a)
| otherwise = \ b -> calcImpl (Left ("Invalid intermediate operator " ++ op))
instance CalcType (Either String Integer) where
calcImpl a op
| op == "=" = a
| otherwise = Left ("Invalid final operator " ++ op)
calc :: CalcType r => Integer -> String -> r
calc = calcImpl . Right
result :: Either String Integer
result = calc 1 "+" 1 "+" 10 "-" 7 "="
main :: IO ()
main = print result
This is rather fragile and very much not recommended for production use, but there it is anyway just as something to (eventually?) learn from.
Here is a simple solution that I'd say corresponds more closely to your Python code than the advanced solutions in the other answers. It's not an idiomatic solution because, just like your Python one, it will use runtime failure instead of types in the compiler.
So, the essence in you Python is this: you return either a function or an int. In Haskell it's not possible to return different types depending on runtime values, however it is possible to return a type that can contain different data, including functions.
data CalcResult = ContinCalc (Int -> String -> CalcResult)
| FinalResult Int
calc :: Int -> String -> CalcResult
calc a "+" = ContinCalc $ \b -> calc (a+b)
calc a "-" = ContinCalc $ \b -> calc (a-b)
calc a "=" = FinalResult a
For reasons that will become clear at the end, I would actually propose the following variant, which is, unlike typical Haskell, not curried:
calc :: (Int, String) -> CalcResult
calc (a,"+") = ContinCalc $ \b op -> calc (a+b,op)
calc (a,"-") = ContinCalc $ \b op -> calc (a-b,op)
calc (a,"=") = FinalResult a
Now, you can't just pile on function applications on this, because the result is never just a function – it can only be a wrapped function. Because applying more arguments than there are functions to handle them seems to be a failure case, the result should be in the Maybe monad.
contin :: CalcResult -> (Int, String) -> Maybe CalcResult
contin (ContinCalc f) (i,op) = Just $ f i op
contin (FinalResult _) _ = Nothing
For printing a final result, let's define
printCalcRes :: Maybe CalcResult -> IO ()
printCalcRes (Just (FinalResult r)) = print r
printCalcRes (Just _) = fail "Calculation incomplete"
printCalcRes Nothing = fail "Applied too many arguments"
And now we can do
ghci> printCalcRes $ contin (calc (1,"+")) (2,"=")
3
Ok, but that would become very awkward for longer computations. Note that we have after two operations a Maybe CalcResult so we can't just use contin again. Also, the parentheses that would need to be matched outwards are a pain.
Fortunately, Haskell is not Lisp and supports infix operators. And because we're anyways getting Maybe in the result, might as well include the failure case in the data type.
Then, the full solution is this:
data CalcResult = ContinCalc ((Int,String) -> CalcResult)
| FinalResult Int
| TooManyArguments
calc :: (Int, String) -> CalcResult
calc (a,"+") = ContinCalc $ \(b,op) -> calc (a+b,op)
calc (a,"-") = ContinCalc $ \(b,op) -> calc (a-b,op)
calc (a,"=") = FinalResult a
infixl 9 #
(#) :: CalcResult -> (Int, String) -> CalcResult
ContinCalc f # args = f args
_ # _ = TooManyArguments
printCalcRes :: CalcResult -> IO ()
printCalcRes (FinalResult r) = print r
printCalcRes (ContinCalc _) = fail "Calculation incomplete"
printCalcRes TooManyArguments = fail "Applied too many arguments"
Which allows to you write
ghci> printCalcRes $ calc (1,"+") # (2,"+") # (3,"-") # (4,"=")
2
A Haskell function of type A -> B has to return a value of the fixed type B every time it's called (or fail to terminate, or throw an exception, but let's neglect that).
A Python function is not similarly constrained. The returned value can be anything, with no type constraints. As a simple example, consider:
def foo(b):
if b:
return 42 # int
else:
return "hello" # str
In the Python code you posted, you exploit this feature to make calc(a)(op) to be either a function (a lambda) or an integer.
In Haskell we can't do that. This is to ensure that the code can be type checked at compile-time. If we write
bar :: String -> Int
bar s = foo (reverse (reverse s) == s)
the compiler can't be expected to verify that the argument always evaluates to True -- that would be undecidable, in general. The compiler merely requires that the type of foo is something like Bool -> Int. However, we can't assign that type to the definition of foo shown above.
So, what we can actually do in Haskell?
One option could be to abuse type classes. There is a way in Haskell to create a kind of "variadic" function exploiting some kind-of convoluted type class machinery. That would make
calc 1 "+" 1 "+" 10 "-" 7 :: Int
type-check and evaluate to the wanted result. I'm not attempting that: it's complex and "hackish", at least in my eye. This hack was used to implement printf in Haskell, and it's not pretty to read.
Another option is to create a custom data type and add some infix operator to the calling syntax. This also exploits some advanced feature of Haskell to make everything type check.
{-# LANGUAGE GADTs, FunctionalDependencies, TypeFamilies, FlexibleInstances #-}
data R t where
I :: Int -> R String
F :: (Int -> Int) -> R Int
instance Show (R String) where
show (I i) = show i
type family Other a where
Other String = Int
Other Int = String
(#) :: R a -> a -> R (Other a)
I i # "+" = F (i+) -- equivalent to F (\x -> i + x)
I i # "-" = F (i-) -- equivalent to F (\x -> i - x)
F f # i = I (f i)
I _ # s = error $ "unsupported operator " ++ s
main :: IO ()
main =
print (I 1 # "+" # 1 # "+" # 10 # "-" # 7)
The last line prints 5 as expected.
The key ideas are:
The type R a represents an intermediate result, which can be an integer or a function. If it's an integer, we remember that the next thing in the line should be a string by making I i :: R String. If it's a function, we remember the next thing should be an integer by having F (\x -> ...) :: R Int.
The operator (#) takes an intermediate result of type R a, a next "thing" (int or string) to process of type a, and produces a value in the "other type" Other a. Here, Other a is defined as the type Int (respectively String) when a is String (resp. Int).

Why does Haskell presume the returned monad type is the same type that is passed as an argument?

Why does this code compile?
--sequence_mine :: Monad m => [m a] -> m [a]
sequence_mine [] = return []
sequence_mine (elt:l) = do
e <- elt
sl <- sequence l
return (e:sl)
Note I intentionally commented out the type declaration here. But the code still compiles and seems to work as expected, even without the type declaration - and this is what surprises me.
To my understanding, ambiguity should arise on this line:
return (e:sl)
The reason is that Haskell shouldn't know which type of monad we are returning. Why does it have to be the same type that we are accepting?
To clarify more. To my understanding, if I don't explicitely put the type declaration analogous to the one I commented out, Haskell should deduce this function has a typing like this:
sequence_mine :: (Monad m1, Monad m2) => [m1 a] -> m2 [a]
Unless I explicitely unify m1 and m2 by calling them both m, there is no reason for Haskell to believe they both refer to the same type! I would suppose.
Yet that is not the case. What am I missing here?
Well, let's look at what the do block desugars to:
sequence_mine (elt:l) = elt >>= \e -> (sequence l) >>= \sl -> return (e:sl)
Recall that the "bind" operator >>= has the type signature (Monad m) => m a -> (a -> m b) -> m b. Note that the monad m here, although arbitrary, must be the same for both of the arguments and the result type.
So if elt has type m a, it's easy to see that the return (e:sl) - which is the output type of the whole expression - must have type m [a], for the same monad m.
To put it another way, each do block only works in the context of a fixed monad.

Why does Haskell point free version of function result in ambiguous type error?

It turns out that in GHC 7.10, this compiles fine:
mysum xs = foldr (+) 0 xs
But this:
mysum = foldr (+) 0
results in the following error:
No instance for (Foldable t0) arising from a use of ‘foldr’
The type variable ‘t0’ is ambiguous
Relevant bindings include
mysum :: t0 Integer -> Integer (bound at src/Main.hs:37:1)
Note: there are several potential instances:
instance Foldable (Either a) -- Defined in ‘Data.Foldable’
instance Foldable Data.Functor.Identity.Identity
-- Defined in ‘Data.Functor.Identity’
instance Foldable Data.Proxy.Proxy -- Defined in ‘Data.Foldable’
...plus five others
In the expression: foldr (+) 0
In an equation for ‘mysum’: mysum = foldr (+) 0
Why does this happen, and what is the insight that's achieved by understanding this difference? Also, can I give this function a type (that's still generic) to make this error go away?
As usual with cases where making a well-typed function point-free suddenly results in type errors about unfulfilled typeclass constraints, the ultimate cause of this is the monomorphism restriction, enabled by default.
You can solve this by either adding a type signature to mysum:
mysum :: (Foldable f, Num a) => f a -> a
or by turning off the monomorphism restriction:
{-# LANGUAGE NoMonomorphismRestriction #-}

Weeding duplicates from a list of functions

Is it possible to remove the duplicates (as in nub) from a list of functions in Haskell?
Basically, is it possible to add an instance for (Eq (Integer -> Integer))
In ghci:
let fs = [(+2), (*2), (^2)]
let cs = concat $ map subsequences $ permutations fs
nub cs
<interactive>:31:1:
No instance for (Eq (Integer -> Integer))
arising from a use of `nub'
Possible fix:
add an instance declaration for (Eq (Integer -> Integer))
In the expression: nub cs
In an equation for `it': it = nub cs
Thanks in advance.
...
Further, based on larsmans' answer, I am now able to do this
> let fs = [AddTwo, Double, Square]
> let css = nub $ concat $ map subsequences $ permutations fs
in order to get this
> css
[[],[AddTwo],[Double],[AddTwo,Double],[Square],[AddTwo,Square],[Double,Square],[AddTwo,Double,Square],[Double,AddTwo],[Double,AddTwo,Square],[Square,Double],[Square,AddTwo],[Square,Double,AddTwo],[Double,Square,AddTwo],[Square,AddTwo,Double],[AddTwo,Square,Double]]
and then this
> map (\cs-> call <$> cs <*> [3,4]) css
[[],[5,6],[6,8],[5,6,6,8],[9,16],[5,6,9,16],[6,8,9,16],[5,6,6,8,9,16],[6,8,5,6],[6,8,5,6,9,16],[9,16,6,8],[9,16,5,6],[9,16,6,8,5,6],[6,8,9,16,5,6],[9,16,5,6,6,8],[5,6,9,16,6,8]]
, which was my original intent.
No, this is not possible. Functions cannot be compared for equality.
The reason for this is:
Pointer comparison makes very little sense for Haskell functions, since then the equality of id and \x -> id x would change based on whether the latter form is optimized into id.
Extensional comparison of functions is impossible, since it would require a positive solution to the halting problem (both functions having the same halting behavior is a necessary requirement for equality).
The workaround is to represent functions as data:
data Function = AddTwo | Double | Square deriving Eq
call AddTwo = (+2)
call Double = (*2)
call Square = (^2)
No, it's not possible to do this for Integer -> Integer functions.
However, it is possible if you're also ok with a more general type signature Num a => a -> a, as your example indicates! One naïve way (not safe), would go like
{-# LANGUAGE FlexibleInstances #-}
{-# LANGUAGE NoMonomorphismRestriction #-}
data NumResLog a = NRL { runNumRes :: a, runNumResLog :: String }
deriving (Eq, Show)
instance (Num a) => Num (NumResLog a) where
fromInteger n = NRL (fromInteger n) (show n)
NRL a alog + NRL b blog
= NRL (a+b) ( "("++alog++ ")+(" ++blog++")" )
NRL a alog * NRL b blog
= NRL (a*b) ( "("++alog++ ")*(" ++blog++")" )
...
instance (Num a) => Eq (NumResLog a -> NumResLog a) where
f == g = runNumResLog (f arg) == runNumResLog (g arg)
where arg = NRL 0 "THE ARGUMENT"
unlogNumFn :: (NumResLog a -> NumResLog c) -> (a->c)
unlogNumFn f = runNumRes . f . (`NRL`"")
which works basically by comparing a "normalised" version of the functions' source code. Of course this fails when you compare e.g. (+1) == (1+), which are equivalent numerically but yield "(THE ARGUMENT)+(1)" vs. "(1)+(THE ARGUMENT)" and thus are indicated as non-equal. However, since functions Num a => a->a are essentially constricted to be polynomials (yeah, abs and signum make it a bit more difficult, but it's still doable), you can find a data type that properly handles those equivalencies.
The stuff can be used like this:
> let fs = [(+2), (*2), (^2)]
> let cs = concat $ map subsequences $ permutations fs
> let ncs = map (map unlogNumFn) $ nub cs
> map (map ($ 1)) ncs
[[],[3],[2],[3,2],[1],[3,1],[2,1],[3,2,1],[2,3],[2,3,1],[1,2],[1,3],[1,2,3],[2,1,3],[1,3,2],[3,1,2]]

Function application: Why is $ used here?

A while ago, I asked a question about $, and got useful answers -- in fact, I thought I understood how to use it.
It seems I was wrong :(
This example shows up in a tutorial:
instance Monad [] where
xs >>= f = concat . map f $ xs
I can't for the life of me see why $ was used there; ghci isn't helping me either, as even tests I do there seem to show equivalence with the version that would simply omit the $. Can someone clarify this for me?
The $ is used here because it has lower precedence than normal function application.
Another way to write this code is like so:
instance Monad [] where
xs >>= f = (concat . map f) xs
The idea here is to first construct a function (concat . map f) and then apply it to its argument (xs). As shown, this can also be done by simply putting parenthesis around the first part.
Note that omitting the $ in the original definition is not possible, it will result in a type error. This is because the function composition operator (the .) has a lower precedence than normal function application effectively turning the expression into:
instance Monad [] where
xs >>= f = concat . (map f xs)
Which doesn't make sense, because the second argument to the function composition operator isn't a function at all. Although the following definition does make sense:
instance Monad [] where
xs >>= f = concat (map f xs)
Incidentally, this is also the definition I would prefer, because it seems to me to be a lot clearer.
I'd like to explain why IMHO this is not the used style there:
instance Monad [] where
xs >>= f = concat (map f xs)
concat . map f is an example of so-called pointfree-style writing; where pointfree means "without the point of application". Remember that in maths, in the expression y=f(x), we say that f is applied on the point x. In most cases, you can actually do a final step, replacing:
f x = something $ x
with
f = something
like f = concat . map f, and this is actually pointfree style.
Which is clearer is arguable, but the pointfree style gives a different point of view which is also useful, so sometimes is used even when not exactly needed.
EDIT: I have replaced pointless with pointfree and fixed some examples, after the comment by Alasdair, whom I should thank.
The reason $ is used here is doe to the type signature of (.):
(.) :: (b -> c) -> (a -> c) -> a -> c
Here we have
map f :: [a] -> [[b]]
and
concat :: [[b]] -> [b]
So we end up with
concat . map f :: [a] -> [b]
and the type of (.) could be written as
(.) :: ([[b]] -> [b]) -> ([a] -> [[b]]) -> [a] -> [b]
If we were to use concat . map f xs, we'd see that
map f xs :: [[b]]
And so cannot be used with (.). (the type would have to be (.) :: (a -> b) -> a -> b