gpt4 book ai didi

haskell - 将类型变量约束为具体类型

转载 作者:行者123 更新时间:2023-12-02 13:16:57 26 4
gpt4 key购买 nike

我有这个单态代码:

import Data.Array.MArray
import Data.Array.IO (IOUArray)
import Data.Ix (Ix)

push :: IOUArray Int Int -> Int -> [Int] -> IO Int
push stack top [] = return top
push stack top (k:ks) = do
v <- readArray stack k
if v >= 0 then push stack top ks
else do writeArray stack k top
push stack k ks

push 的完全多态签名将是:

push :: (MArray a e m, Ix e, Num e)  => a e e -> e -> [e] -> m e

但我尝试编写这些部分多态签名:

push :: MArray a e m => a Int e -> Int -> [Int] -> m Int
push :: MArray a e m => a Int Int -> Int -> [Int] -> m Int
push :: MArray a Int m => a Int Int -> Int -> [Int] -> m Int
push :: (MArray a e m, e ~ Int) => a e e -> e -> [e] -> m e

并且我收到诸如 can't derive (e ~ Int)can't derduc (MArray a Int m) ...Non 之类的错误约束中的类型变量参数非法方程约束

有没有办法将第一个签名中的类型变量e限制为Int等具体类型?

最佳答案

如果您启用FlexibleContexts,则第三个签名有效(如错误所示):

{-# LANGUAGE FlexibleContexts #-}
import Data.Array.MArray
import Data.Array.IO (IOUArray)
import Data.Ix (Ix)

push :: MArray a Int m => a Int Int -> Int -> [Int] -> m Int
-- push :: IOUArray Int Int -> Int -> [Int] -> IO Int
push stack top [] = return top
push stack top (k:ks) = do
v <- readArray stack k
if v >= 0 then push stack top ks
else do writeArray stack k top
push stack k ks

some discussion of this extension在 Haskell Prime wiki 上。

第四个签名与TypeFamilies配合使用以允许e ~ Int约束:

{-# LANGUAGE TypeFamilies #-}
import Data.Array.MArray
import Data.Array.IO (IOUArray)
import Data.Ix (Ix)

push :: (MArray a e m, e ~ Int) => a e e -> e -> [e] -> m e
-- push :: IOUArray Int Int -> Int -> [Int] -> IO Int
push stack top [] = return top
push stack top (k:ks) = do
v <- readArray stack k
if v >= 0 then push stack top ks
else do writeArray stack k top
push stack k ks

在这种特殊情况下,我认为它对调用上下文的类型检查与 FlexibleContexts 的其他工作签名具有完全相同的效果,但一般来说,具有具有等式约束的类型变量并不完全一样与具有具体类型相同。

关于haskell - 将类型变量约束为具体类型,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/21943008/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com