The openness of the functions of functional languages

I am currently learning Clojure and it is very intellectually stimulating, but I have encountered many situations where I can program a solution to a problem (for example, using 4Clojure as an example), but find other solutions to use a large number of other functions that I am absolutely not about I suspect.

, , , ? , . , , , ? ? - , .

, , . , foldl foldr, , foldl ' ( ) foldr' ? - " " , .

- - , ?

+3




2


!: D

A good start, according to many, is being able to talk about types. In the Haskell world, they even have a type-based search engine! Let's say for example you have a value of type Maybe Int

and you want to convert it to a string if there is a value there, otherwise supply an empty string. In terms of type, this is a function

f' :: Maybe Integer -> (Integer -> String) -> String -> String

      

It takes three arguments - value Maybe

, conversion function, default, and it will return a string. If we make this more general we can end up with something like

f :: Maybe a -> (a -> b) -> b -> b

      

using this as a type-based search engine query , we find that there is indeed a function

maybe :: b -> (a -> b) -> Maybe a -> b

      

in a library Data.Maybe

that does what we want.

Types: (

Of course, this is not ideal. One problem is that you can express the same operation at different levels of abstraction. Imagine, for example, that we have a list of integers that we want to convert to values Text

and then concatenate. First attempt at type signature results in something line by line

g' :: [Int] -> (Int -> Text) -> Text

      



If we are looking for this, we will not find a clear result. It is impossible to immediately figure out how to make this more abstract. Maybe it should be something like this?

g :: [a] -> (a -> b) -> ([b] -> b) -> b

      

(In other words, given a list a

, a transform function, and a function that tells you how to concatenate b

s, return one b

.) Searching for this result yields many results, all of which are completely irrelevant to our application.

The key insight here, which doesn't come with reasoning but with experience and knowledge, is that we really want something that already knows how to concatenate itself. We need an operational function Monoid

. Based on this knowledge, we are more likely to find

foldMap :: (Foldable t, Monoid m) => (a -> m) -> t a -> m

      

- exactly what we were looking for.

Conclusion

Thus types are not a perfect system, but they do help. The reason they work is because they try to code the intent of the programmer. What you are really asking for is some kind of database of intents, not implementations (as source code.)

Better systems can make this process smoother by allowing the programmer to better code their intentions. But they will always require discipline, for example using the most common type available.

The case for more general types is that more general types limit the number of intents that fall under the same type. A function with a type a -> b -> a

can, in the absence of context, do only one thing: ignore its second argument and return the first. On the other hand, a type function String -> b -> String

can do almost anything it wants because it knows how to construct the value of its own return type. If a function does not know its return type, it can only construct it using the arguments it receives.

+6


source


Haskell has a hoogle where you can search based on the type signature (and name). I found this to be very helpful in teaching. As long as you know what you are trying to achieve, you will most likely find something close to what you need.



For example, you can search for (b-> c) -> (a-> b) -> a -> c and the search calls up, among other things, (.), Which is used to compose functions.

0


source







All Articles