At the word TRIZ, one often recalls the thesis “an ideal system is one that does not exist (and its function is fulfilled)”. As a good admin, who does not appear in the office, but everything works fine.
Function and system are crucial concepts in TRIZ, they even speak about the functional style of thinking. True, with these words, I personally immediately have an association with functional programming languages.
Let's try to see how organically the ideas of functional thinking of TRIZ are mapped to Haskell, one of the pure functional general purpose languages.

Function
A function is a model for changing the property of an object of a function ("item") by the carrier of a function ("tool").
The tool is that with the help of which we do some work, i.e. change something. As a rule, it needs to be improved or created. Accordingly, it is the carrier of the function that is usually meant by the word "system" in all TRIZ arguments about it.
The product is what we change (process) with the tool.

The main function is a consumer property, for the satisfaction of which a technical system is being created.
The function itself is usually given by a simple verb reflecting the essence of the process (not by a special term so that the inertia of thinking does not interfere); the carrier and the object of the function are included in the formulation.
For example: a hammer moves a nail; broom moves trash; cup holds coffee; vacuum cleaner moves dust; fuel moves the rocket.
Consider, in particular, a cup of coffee.
The cup holds the coffee.
The function carrier (tool) is a cup, the function object is coffee, the function is hold.

-- -- , - hold :: Cup -> Coffee -> Coffee -- hold - "" cup `hold` coffee
The hold function must be polymorphic, since a cup can hold not only coffee and coffee can be poured not only into the cup:
-- b, b hold :: a -> b -> b -- , thermos `hold` coffee -- , shirt `hold` coffee
The tool and the product can change, but the essence of their interaction, expressed by the function, remains the same. According to statistics, most of the paired functions between elements of technical systems can be described by three dozen verbs (move, hold, heat, absorb, inform, etc.). Each of them, from the Haskell implementation point of view, is a polymorphic function. As, however, and other verbs of a natural language.
Inverse function
In the real world, there is always an inverse function - the action of the product on the instrument (no one has repealed Newton's third law).

For example, the metal being processed blunts the drill, the careless student tires the teacher, the file reduces the free space on the disk.
In the coffee example, it heats and soils the cup.

As a rule, the inverse function harms us (tool wear, additional costs), but in other situations we can benefit from it. For example, warm your hands on a warm cup, being in a cool room.
hold:: a -> b -> b warm :: a -> b -> b cup `hold` coffee coffee `warm` cup
Function chains
In the case when the number of system elements is more than two (i.e., in fact, always), they are considered in pairs, obtaining chains of functions.
For example, in the picture below, the hand carries (moves) the tray with the cup, the tray holds the cup, the cup holds the coffee.

((arm `move` wrist) `hold` cup) `hold` coffee
We get rid of the brackets by specifying the left associativity
infixl 9 hold arm `move` wrist `hold` cup `hold` coffee
Haskell recording is very close to natural language recording.
And the chain in the opposite direction: the coffee heats the cup, the cup heats the saucer, the saucer loads the hand.
infixl 9 warm, weight coffee `warm` cup `warm` wrist `weight` arm
Understanding the main function and interactions between the elements allows you to optimally choose the boundaries of the system, include only what is needed to perform the target task (without missing anything) and not complicate the model beyond what is necessary.
A system that does not exist ...
We need a function, or rather the result of its use, and the tool itself is not needed. It is a consumable material, attracted only by necessity.
Hold coffee can jazz, kettle, thermos, saucer and table and shirt (if coffee is carelessly spilled).
We even would not mind if the CAM itself held the coffee. As it happens, for example, with water in zero gravity on a space station.

However, it is not customary to dwell on looped formulations like “coffee keeps coffee” in TRIZ, since it is useless from a practical point of view - it does not provide information about the elements, due to which the result is achieved.
From a programming point of view, such a recursive formulation is bad because there is no condition for the end of recursion.
It is necessary to go into depth and specify exactly which parts (subsystems) provide the function.
The liquid takes a compact form in weightlessness due to surface tension forces. So a more appropriate description of the situation would be: the surface layer holds the internal volume of coffee.
You can imagine the entire volume of coffee as a matryoshka doll of layers, each of which holds each other. In this case, the main work is done by the outer layer.

-- - , - let coffee = [layer1, layer2, layer3, layer4, layer5] head coffee `hold` tail coffee
However, if the influence of the layers on each other is important to us (for example, in terms of light absorption),
you can invent a bicycle and describe successive interactions explicitly.
The recursive nature of the phenomenon is preserved, but by understanding the interconnections of the subsystems we will be able to set the conditions for exiting recursion and turn it into our service.

-- "", hold :: String -> String -> String hold tool "" = tool hold tool workpiece = tool ++ " -> holds -> " ++ workpiece -- " ". -- -- "" -- selfHold :: [String] -> String selfHold [] = "" selfHold (x:xs) = x `hold` selfHold xs -- selfHold ["Layer1","Layer2","Layer3"]
in the end we get
Layer1 -> holds -> Layer2 -> holds -> Layer3
The recursiveness of the implementation has not disappeared anywhere, but it has become constructive, and not meaninglessly fixated.
The same can be written down and shorter, by convolving the list:
foldl1 hold ["Layer1","Layer2","Layer3"]
Conclusion
The vision of a technical system as a fabric from the functions linking it into one and determining the essence and purpose, extremely unites TRIZ with functional programming languages, in which the function is the main control structure.
The considered approach serves as a good support in terms of task decomposition and model complexity management.