我想創建一個SML函數,根據它接受的字符串返回true或false。如果它只包含數字,則返回true,否則返回false。SML檢查一個字符串是否只包含數字
例如: 「4124」 - 真正的
「543.234」 - 假
「F42」 - 假
「344克」 - 假
我並不擅長使用SML,任何幫助將不勝感激。
我想創建一個SML函數,根據它接受的字符串返回true或false。如果它只包含數字,則返回true,否則返回false。SML檢查一個字符串是否只包含數字
例如: 「4124」 - 真正的
「543.234」 - 假
「F42」 - 假
「344克」 - 假
我並不擅長使用SML,任何幫助將不勝感激。
fun foo xs = length (List.filter (Char.isDigit) xs) = length xs;
fun boo xs = foo (explode xs);
根據需要重命名該函數。
fun boo xs = List.all (Char.isDigit) (explode xs)
也有效。
定義
val allDigits = List.all Char.isDigit o explode;
(或類似的東西)是自然和優雅,但有缺點,它掃描過來的數據兩次,第一次創建人物的名單,另一次檢查,如果一切這些字符是數字。 SML的急切評估意味着即使第一個字符不是數字,也會創建整個列表。這會導致該功能例如採取超過200,000步驟來驗證Moby Dick的文本不是全部數字。
解決方案是抵制爆炸的字符串。相反,使用索引。
是有幫助的第一引入功能,其中當傳遞的函數int -> bool
類型的f
和一對整數a
和b
返回真,如果在間隔[a,b)
所有整數滿足謂詞f
:
fun allInRange f (a,b) =
if b <= a then
true
else
f a andalso allInRange f (a+1,b);
由於SML短路andalso
,只要在範圍內找到f
的反例(如果有的話 - 否則返回true
當然),遞歸終止。
最後,
fun allDigits s =
let
fun f i = Char.isDigit (String.sub (s,i))
in
allInRange f (0, String.size s)
end;
你嘗試過什麼?這是作業,重點是從使用基本遞歸的第一原理開始,或者是其他事情需要的實際問題(在這種情況下,使用「List.all」和「Char.isDigit」的單行解決方案'是要走的路)? –