如何在haskell中分解复杂的类型别名



我遇到了这个非常古老的数独代码,它对我来说似乎是希腊语,因为主要是这种丑陋的类型

type T = (Int,Int) -> [Int]

为了理解这个功能,例如

mark :: ((Int,Int),Int) -> T -> T
mark (p@(i,j),n) s q@(x,y) =
  if p==q then [n] else
  if x==i || y==j || e x i && e y j then delete n $ s q else s q
  where e a b = div (a-1) 3==div (b-1) 3

我可以用实际类型的代替T

mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]
mark (p@(i,j),n) s q@(x,y) = 

现在,类型参数似乎没有正确排列。p完全匹配,但我把它和"s"搞混了。如果我加入对马克的呼吁,它是这样的。。。。。在这里的列表中,我可以很容易地看到它的键值对数组,其中包含(1,2)等键。这些键在数独中已被过滤为空格或零。

input :: String -> (Int,Int) -> [Int]
input s = foldr mark (const [1..9]) $
   [(p,n) | (p,n) <- zip idx $ map read $ lines s >>= words, n>0]

标记函数是用这个列表和累加器调用的,累加器是一个函数(const[1..9])。这不适合类型签名。

mark :: ((Int,Int),Int) -> (Int,Int)->[Int] -> (Int,Int)->[Int]

代码的问题是我看不到标记函数的实际结果,但我仍然不理解。当它被传递给第三个函数时,它会得到一些输出。关于如何理解这个sphagetti代码,有什么解释吗?

此类型的值

type T = (Int,Int) -> [Int]

将任何数独单元CCD_ 1的坐标映射到该单元可能具有的一组可能值(表示为数字列表CCD_。

函数const [0..9]将任何单元格映射到所有数字的集合中。它充当数独求解器的初始状态:在开始时,假设任何单元格都可以有任何数字。

最新更新