如何用Haskell脚本实现指定大小的单位矩阵生成函数
实现Haskell的单位矩阵生成函数
identity 首先明确你的需求:
- 类型别名:
type Matrice a = [[a]] - 函数签名:
identity :: Int -> Maybe (Matrice Int) - 核心规则:
- 输入的矩阵大小小于1时,返回
Nothing - 输入大小
n ≥ 1时,返回Just包裹的n阶单位矩阵(对角线元素为1,其余为0的方阵)
- 输入的矩阵大小小于1时,返回
你现有代码的问题
先看你写的两段代码,存在几个影响编译和逻辑的问题:
- 语法错误:
identity1的第一个分支漏掉了=,写成了| a == 0 [],正确写法应该是| a == 0 = [] - 函数名不统一:递归调用时混用了
identity、identity',但你定义的函数是identity1和identity2,这会导致编译报错 - 逻辑偏差:
identity1的分支逻辑没抓住“对角线位置为1”的核心,参数的含义也不清晰,比如b ==0时的处理完全不符合单位矩阵的行生成逻辑 - 括号缺失:
identity2的最后一行结尾少了闭合括号,语法不完整
正确实现思路
其实用Haskell的列表推导式可以很简洁地实现这个功能,不用拆成多个辅助函数。我们可以这样拆解:
- 先做边界判断:如果输入的
n <1,直接返回Nothing - 对于合法的
n,生成n行,每一行的第i个位置(行索引等于列索引时)设为1,其余为0
完整正确代码
type Matrice a = [[a]] identity :: Int -> Maybe (Matrice Int) identity n | n < 1 = Nothing | otherwise = Just [ [ if i == j then 1 else 0 | j <- [0..n-1] ] | i <- [0..n-1] ]
代码解释
- 边界处理:第一行守卫直接拦截所有小于1的输入,返回
Nothing,完全符合需求 - 列表推导式:
- 外层的
[ ... | i <- [0..n-1] ]负责生成每一行,i代表当前行的索引(从0到n-1) - 内层的
[ if i == j then 1 else 0 | j <- [0..n-1] ]生成当前行的每个元素,j是列索引,当行索引和列索引相等时就放1,否则放0
- 外层的
- 最后用
Just把生成的矩阵包起来,完美匹配函数的返回类型
测试验证
- 输入
5:返回Just [[1,0,0,0,0],[0,1,0,0,0],[0,0,1,0,0],[0,0,0,1,0],[0,0,0,0,1]] - 输入
2:返回Just [[1,0],[0,1]] - 输入
0或负数:返回Nothing
内容的提问来源于stack exchange,提问作者Anna
相关产品推荐
相关产品推荐

