I stumbled upon LiquidHaskell by chance. This refined type system appears to enhance static checks, thereby providing more robust compile-time validation.
However, I have a question regarding how it verifies the expected range of values statically. The code below illustrates the definition of a take
function.
{-@ take' :: xs:[a] -> {i:Int | i < len xs} -> [a] @-}
take' :: [a] -> Int -> [a]
take' _ 0 = []
take' [] _ = []
take' (h:t) s = h : take' t (s - 1)
-- work
ex1 = take' [1,2,3,4,5] 4
-- does not work
ex2 = take' l 4
where l = take 5 (repeat 3) -- [3,3,3,3,3]
The first example ex1
works, but not the case of ex2
.
- Could someone clarify the distinctions in the way LiquidHaskell handles āex1ā and āex2ā?
- I havenāt tested command-line inputs, file inputs, or any external inputs. I assume that external inputs should also fail if they are fed to
take
function as input. If this assumption is accurate, what is the appropriate context within which LiquidHaskell can be utilized, and what are the expected use cases for it?
Thank you.