def promedio (nums: List[Int]): Int = nums.reduce(_ + _) / nums.length
Que podría ir mal aquí?
Como podríamos resolverlo?
def promedio (nums: List[Int]): Int = {
if (nums.isEmpty)
throw IllegalArgumentException("La lista no puede ser vacía")
nums.reduce(_ + _) / nums.length
}
Y esto:
Se puede mejorar?
def promedio (nums: NonEmptyList[Int]): Int = nums.reduce(_ + _) / nums.length
Que tal esto?
def definition (word: String, dict: Map[String, String]): String = dict(word)
Otra situación:
Como podríamos resolverlo?
def definition (word: String, dict: Map[String, String]): Option[String] =
dict.get(word)
Y esto:
Se puede mejorar?
def definition (word: String)
(dict: Map[String, String] Refined Contains[word.type])
: String = dict(word)
Que tal esto:
def at (idx: Int, list: List[String]): String = list(idx)
def fraction (num: Int, div: Int): (Int, Int) = (num, div)
at(9, 1 :: 2 :: 3 :: Nil) // No compila
fraction(1, 0) // No compila
Dos más:
type NonZero = Or[Positive, Negative]
case class Fraction(numerator: Int, denominator: Int Refined NonZero)
Fraction(1, 3)
Fraction(1, 0) //Does not compile
Fraction:
class BetweenAux[N <: Int](start: Witness.Aux[N]) {
def apply(end: Int Refined Greater[N]): Int Refined Positive =
Refined.unsafeApply(end - start.value)
}
def between(n: Int) = new BetweenAux(Witness(n))
between(2)(5)
between(6)(1) //Does not compile
Between:
@unique : Variable, parametro o resultado único
@transient : parametro no consumible (prestado)
@peer(x) : Parametro o resultado en la misma región que x
capture(x, y) : Transfiere x a la región de y y retorna un alias de x
swap(x.f, y) : Intercambia dos valores únicos
(via plugin de compilador en scala)
val buf: ArrayBuffer[Int] @unique = new ArrayBuffer[Int]
buf += 5
consume buf
buf.remove(0) // No compila
let v = vec![1, 2, 3];
let v2 = v;
println!("v[0] is: {}", v[0]); // No compila
Scala
Rust
class LogList {
var elem: LogFile = null
var next: LogList = this
@transient def add(file: LogFile @peer(this)) =
if (isEmpty) { elem = file; next = new LogList }
else next.add(file)
}
val logList: LogList @unique = new LogList
for (test <- tests) {
val logFile: LogFile @unique = createLogFile(test)
// realizar computación...
logList.add(capture(logFile, logList))
}
Transferencias más elaboradas
import Control.ST
data Access = LoggedOut | LoggedIn
data LoginResult = OK | BadPassword
interface DataStore (m : Type -> Type) where
data Store : Access -> Type
connect : ST m Var [add (Store LoggedOut)]
disconnect : (store : Var) -> ST m () [remove store (Store LoggedOut)]
readSecret : (store : Var) -> ST m String [store ::: Store LoggedIn]
login : (store : Var) ->
ST m LoginResult [store ::: Store LoggedOut :->
(\res => Store (case res of
OK => LoggedIn
BadPassword => LoggedOut))]
logout : (store : Var) ->
ST m () [store ::: Store LoggedIn :-> Store LoggedOut]
getData : (ConsoleIO m, DataStore m) => ST m () []
getData = do st <- connect
OK <- login st
| BadPassword => do putStrLn "Failure"
disconnect st
secret <- readSecret st
putStrLn ("Secret is: " ++ show secret)
logout st
disconnect st
-- badGet : DataStore m => ST m () []
-- badGet = do st <- connect
-- secret <- readSecret st
-- disconnect st
DataStore IO where
Store x = State String -- represents secret data
connect = do store <- new "Secret Data"
pure store
disconnect store = delete store
readSecret store = readSecret store
login store = do putStr "Enter password: "
p <- getStr
if p == "Mornington Crescent"
then pure OK
else pure BadPassword
logout store = pure ()
main : IO ()
main = run getData
https://github.com/fthomas/refined
http://ucsd-progsys.github.io/liquidhaskell-tutorial/01-intro.html
https://ncatlab.org/nlab/show/intrinsic+and+extrinsic+views+of+typing
http://www.weaselhat.com/2015/03/16/a-refinement-type-by-any-other-name/
http://lampwww.epfl.ch/~phaller/doc/capabilities-uniqueness2.pdf
https://www.irif.fr/~mellies/papers/functors-are-type-refinement-systems.pdf
http://theses.gla.ac.uk/5244/1/2013McGinnissPhD.pdf
https://www.di.fc.ul.pt/~vv/papers/baltazar.mostrous.vasconcelos_linearly-refined-session-types.pdf
http://docs.idris-lang.org/en/latest/reference/uniqueness-types.html
http://pcwalton.github.io/blog/2012/12/26/typestate-is-dead/
Rodolfo Hansen @kryptt