scr*_*avy 9 haskell exception-handling
我写了一个haskell函数,它将列表拆分xs
成(init xs, last xs)
如下:
split xs = split' [] xs
where
split' acc (x:[]) = (reverse acc, x)
split' acc (x:xs) = split' (x:acc) xs
Run Code Online (Sandbox Code Playgroud)
由于无法以这种方式拆分空列表,因此空列表不匹配.但是,我不想简单地使用error ...
这个功能.因此我定义了以下内容:
split [] = ([], undefined)
Run Code Online (Sandbox Code Playgroud)
由于懒惰的评估,我可以定义一个安全init
,它只返回空列表的空列表:
init' = fst . split
Run Code Online (Sandbox Code Playgroud)
如果我试图访问它,有什么方法可以检测到undefined,这样
last' xs
| isUndefined (snd xs) = ...
| otherwise = ...
Run Code Online (Sandbox Code Playgroud)
我不知道Maybe
和Either
的,而那些对于表达我想要的是更好的选择.但是我想知道是否有办法检测未定义的实际值,即捕获错误,如捕获异常.
sha*_*ang 11
undefined
并不比使用更好error
.事实上,undefined
Prelude被定义为
undefined = error "Prelude.undefined"
Run Code Online (Sandbox Code Playgroud)
现在,一个不能产生a的函数error
被称为"总函数",即它对所有输入值都有效.
split
您当前实现的功能具有签名
split :: [a] -> ([a], a)
Run Code Online (Sandbox Code Playgroud)
这是一个问题,因为类型签名承诺结果总是包含一个列表和一个元素,这显然不可能为泛型类型的空列表提供.
Haskell中用于解决此问题的规范方法是更改类型签名,以表示有时我们没有第二个项的有效值.
split :: [a] -> ([a], Maybe a)
Run Code Online (Sandbox Code Playgroud)
现在,您可以为获得空列表的情况编写正确的实现
split [] = ([], Nothing)
split xs = split' [] xs
where
split' acc (x:[]) = (reverse acc, Just x)
split' acc (x:xs) = split' (x:acc) xs
Run Code Online (Sandbox Code Playgroud)
现在,您可以通过模式匹配来检测缺失值大小写
let (init', last') = split xs
in case last' of
Nothing -> ... -- do something if we don't have a value
Just x -> ... -- do something with value x
Run Code Online (Sandbox Code Playgroud)
Ing*_*ngo 10
因为底部包含非终止,所以该函数isUndefined
必须解决暂停问题,因此不能存在.
但请注意,即使它存在,您仍然无法判断元组的第二个元素中的未定义值是否通过您的split
函数放在那里,或者列表的最后一个元素是否已经未定义.
在error
评估之前,该函数不会执行任何操作,因此您可以执行以下操作:
split [] = ([], error "split: empty list")
last' = snd . split
Run Code Online (Sandbox Code Playgroud)
归档时间: |
|
查看次数: |
1475 次 |
最近记录: |