相关疑难解决方法(0)

Haskell:默认约束类型

考虑这个例子:

applyKTimes :: Integral i => i -> (a -> a) -> a -> a
applyKTimes 0 _ x = x
applyKTimes k f x = applyKTimes (k-1) f (f x)

applyThrice :: (a -> a) -> a -> a
applyThrice = applyKTimes 3
Run Code Online (Sandbox Code Playgroud)

3applyThrice通过GHC默认为一个Integer与编译时如图所示-Wall:

Warning: Defaulting the following constraint(s) to type 'Integer'
         'Integral t'
           arising from a use of 'applyKTimes'
Run Code Online (Sandbox Code Playgroud)

所以我猜这Integer是默认的Integral a => a.

  • 有没有办法为其他约束定义"默认类型"?
  • 使用默认类型不好的做法?(使用时确实抱怨-Wall …

haskell typeclass

18
推荐指数
1
解决办法
2980
查看次数

函数的Haskell类型推断

最近我一直在玩Haskell,特别是整个仿函数概念.我越深入其中,我得到的时刻越多,它肯定会让我的多巴胺受体相当多.

我坚持的问题如下.这是有效的代码,它提升了函数,然后首先将其应用于IO值,然后应用于List.

replicator1 =
  fmap (replicate 3)

replicator2 =
  fmap (replicate 3)

main = do
  replicated <- replicator1 getLine
  print (replicator2 replicated)
Run Code Online (Sandbox Code Playgroud)

以更简洁的方式编写它是非常诱人的,即:

replicator =
  fmap (replicate 3)

main = do
  replicated <- replicator getLine
  print (replicator replicated)
Run Code Online (Sandbox Code Playgroud)

我的一部分说它在概念上是正确的,因为replicator它既可以应用于IO也可以应用于List实例,但是作为强类型语言Haskell不允许我这样做.我想我非常明白为什么会这样.

问题是:有什么方法可以让我更接近后一种变体?或者和前者住在一起好吗?

谢谢!

haskell functor monomorphism-restriction

8
推荐指数
1
解决办法
105
查看次数

使用uncurry函数的特定类型推断

我一直在玩uncurryGHCi 的功能,我发现了一些我根本无法得到的东西.当我申请uncurry(+)功能,并结合该像在下面的代码中的一些变量,所述编译器推断它的类型是特定于Integer:

Prelude> let add = uncurry (+)
Prelude> :t add
add :: (Integer, Integer) -> Integer
Run Code Online (Sandbox Code Playgroud)

但是,当询问以下表达式的类型时,我得到(我期望的)正确的结果:

Prelude> :t uncurry (+)
uncurry (+) :: (Num a) => (a, a) -> a
Run Code Online (Sandbox Code Playgroud)

会导致什么?这是GHCi特有的吗?

这同样适用于let add' = (+).

注意:我无法使用编译文件重现它.

haskell types ghc monomorphism-restriction

6
推荐指数
1
解决办法
359
查看次数

当用作多种类型的值时,如何处理这种多态值?

鉴于这行代码(我在这个答案中首次看到):

pVal :: Num a => a
pVal = sum . map fromIntegral $ ([1..10000000] :: [Int])
Run Code Online (Sandbox Code Playgroud)

如果它被用作多种类型,那么表达式是否为每种类型完全重新评估?每种类型都有一个结果吗?

例如:

pInt :: Int
pInt = pVal

pDub :: Double
pDub = pVal
Run Code Online (Sandbox Code Playgroud)

polymorphism haskell

3
推荐指数
1
解决办法
89
查看次数

类型推断细微之处

我在理解为什么推断类型签名与我期望的不同时遇到了一些困难.让我们举个例子(我试着让它尽可能短):

import Control.Applicative
import Data.Word
import Text.ParserCombinators.Parsec
import Text.ParserCombinators.Parsec.Token
import Text.Parsec.Language (emptyDef)
import Text.Parsec.Prim
import Data.Functor.Identity

--parseUInt' :: Num b => ParsecT String u Identity b
parseUInt' = fromInteger <$> decimal (makeTokenParser emptyDef)
--parseUInt1 = fromInteger <$> decimal (makeTokenParser emptyDef)
--parseUInt2 = fromInteger <$> decimal (makeTokenParser emptyDef)

parsePairOfInts = do
    x <- parseUInt'
    char ','
    y <- parseUInt'
    return $ (x, y)

parseLine :: String -> Either ParseError (Word32, Word8)
parseLine = parse parsePairOfInts "(error)"

main = print . show …
Run Code Online (Sandbox Code Playgroud)

haskell parsec

3
推荐指数
1
解决办法
106
查看次数

无法将预期类型"a"与实际类型"Double"匹配:

我通过从ghci检查它来声明类型声明但是加载模块会给出错误:

even-fibbanaci-sum.hs:7:12: error:
     Couldn't match expected type ‘a’ with actual type ‘Double’
     ‘a’ is a rigid type variable bound by
       the type signature for:
         getFib :: forall b a. (Integral b, Floating a) => b -> a
       at even-fibbanaci-sum.hs:4:12
     In the expression: ((phi ^ n) - (minusphi ^ n)) / sqrt 5
     In an equation for ‘getFib’:
         getFib n = ((phi ^ n) - (minusphi ^ n)) / sqrt 5    • Relevant bindings include
       getFib :: b -> a (bound …
Run Code Online (Sandbox Code Playgroud)

haskell

2
推荐指数
1
解决办法
1294
查看次数

如何重用不同类型的IO提升功能?

以下代码

import Control.Applicative
import Control.Arrow
import Data.List.Split

main :: IO ()
main = do
    ints <- getNumberLine
    integers <- getNumberLine
    print $ foo ints integers

getNumberLine = readDataLine <$> getLine

readDataLine :: Read a => String -> [a]
readDataLine = splitOn " " >>> map read

foo :: [Int] -> [Integer] -> String
foo _ _ = "hello"
Run Code Online (Sandbox Code Playgroud)

给出此错误消息:

GetNumberLine.hs:9:22:
    Couldn't match type `Int' with `Integer'
    Expected type: [Integer]
      Actual type: [Int]
    In the second argument of `foo', namely `integers' …
Run Code Online (Sandbox Code Playgroud)

haskell type-inference

1
推荐指数
1
解决办法
76
查看次数