Haskell polyvarian function without arguments

I am trying to create a polyvarian function in Haskell, I used this one to create a basic function. Here is the function code:

class SumRes r where 
    sumOf :: Integer -> r

instance SumRes Integer where
    sumOf = id

instance (Integral a, SumRes r) => SumRes (a -> r) where
    sumOf x = sumOf . (x +) . toInteger

But the problem is that when a function is called without any arguments, it does not work.

Couldn't match expected type 'Integer' with actual type 'Integer -> r0'
    Probable cause: 'sumOf' is applied to too few arguments

For example, I would like to write sumOf :: Integerand return this function 0.

How should I do it?

+4
source share
1 answer

The simplest version only works for results Integer.

Easy way

This works with what you already wrote, using what 0is the identifier to add.

class SumRes r where
  sumOf' :: Integer -> r

instance SumRes Integer where
  sumOf' = toInteger

instance (Integral b, SumRes r) => SumRes (b -> r) where
  sumOf' a b = sumOf' $! a + toInteger b

sumOf :: SumRes r => r
sumOf = sumOf' 0

Integer b -> r .

, , , , , Integer . MultiParamTypeClasses TypeFamilies.

{-# LANGUAGE ScopedTypeVariables, AllowAmbiguousTypes, DataKinds,
      KindSignatures, TypeApplications, MultiParamTypeClasses,
      TypeFamilies, FlexibleInstances #-}

module SumRes2 where

data Nat = Z | S Nat
class SumRes (c :: Nat) r where
  sumOf' :: Integer -> r

type family CountArgs a :: Nat where
  CountArgs (_ -> r) =  (CountArgs r)
  CountArgs _ = 'Z

instance Num r => SumRes 'Z r where
  sumOf' = fromInteger

instance (Integral b, SumRes n r) => SumRes ( n) (b -> r) where
  sumOf' a b = sumOf' @n (a + toInteger b)

sumOf :: forall r n. (SumRes n r, CountArgs r ~ n) => r
sumOf = sumOf' @n 0

, Integral , sumOf . . TypeApplications AllowAmbiguousTypes , , , - Tagged.

+5

Source: https://habr.com/ru/post/1685168/


All Articles