- Learn Scala Programming
- Slava Schmidt
- 376字
- 2021-06-10 19:35:51
Partial functions
The possibility of having additional methods gives a way do define concepts that would be hard to state otherwise, at least without extending the language itself. One such example is partial functions. A partial function is a function that is undefined for some values of its arguments. The classical example is a division that is not defined, for the divider equals zero. But actually, it is possible to have arbitrary domain rules that make some function partial. For instance, we could decide that our string reverse function should be undefined for empty strings.
There are a couple of possibilities for implementing such constraints in a program:
- Throw an exception for arguments for which the function is not defined
- Constrain the type of an argument so that it is only possible to pass a valid argument to the function, for example using refined types
- Reflect the partiality in the return type, for example using Option or Either
There are obvious tradeoffs related to each of these approaches and in Scala, the first one is preferred as most natural. But, to better model the partial nature of the function, there is a special trait available in the standard library:
trait PartialFunction[-A, +B] extends (A => B)
The key difference to normal function is that there is an additional method available that allows us to check whether the function is defined for some argument or not:
def isDefinedAt(x: A): Boolean
This allows the user of the function to do something different for "invalid" input values.
For example, let's imagine we've invented a very efficient method to check if a string is a palindrome. Then we could define our reverse function as two partial functions, one that is only defined for palindromes and does nothing and another that is defined only for non-palindromes and does the actual reverse action:
val doReverse: PartialFunction[String, String] = {
case str if !isPalindrome(str) => str.reverse
}
val noReverse: PartialFunction[String, String] = {
case str if isPalindrome(str) => str
}
def reverse = noReverse orElse doReverse
Here we're using syntactic sugar again to define our partial functions as a pattern match and compiler creates isDefinedAt method for us. Our two partial functions are combined into the total function using the orElse method.
- HTML5移動Web開發技術
- Vue.js入門與商城開發實戰
- PostgreSQL技術內幕:事務處理深度探索
- Java FX應用開發教程
- Python Data Analysis(Second Edition)
- Learning Three.js:The JavaScript 3D Library for WebGL
- Procedural Content Generation for C++ Game Development
- Python 3.7從入門到精通(視頻教學版)
- 零基礎學C語言程序設計
- Java圖像處理:基于OpenCV與JVM
- MySQL程序員面試筆試寶典
- C語言程序設計與應用(第2版)
- uni-app跨平臺開發與應用從入門到實踐
- Android Sensor Programming By Example
- Mastering Machine Learning with R