3

So the problem is in understandig HLists of shapeless library https://github.com/milessabin/shapeless ; I'm using HLists to store some functions i.e. :

val list = HList(
    function1(_),
    function2(_),
    ....
    functionn(_)
);

And it works perfect: I can take any function from list and apply it: list.head(object)

But, i have problem applying it with map function (list map mapFunc):

object mapFunc extends Poly1 {
  implicit def default[T] =
    at[T](t => {
      t(obj)
    })
}

It says Application doesnt take parameters. So how can i deal with it? Mb I dont understand smth? I'm new to Scala.

p.s. there is an interesting effect with constructor this code is building lil bit incorrect:

function1(_) :: function2(_) :: HNil it is recognized as function of some type, but HList(function1(_), function2(_)) has the right type.

EDIT

'p.s.' was decided - function1(_) :: function2(_) :: HNil really has type mismatch; but function1 _ :: function2 _ :: HNil is ok!

DaunnC
  • 1,301
  • 15
  • 30

1 Answers1

4

First for your last question—you need to conclude the list with HNil, not HList. So if for example we have the following:

def function1(s: String) = "foo " + s
def function2(s: String) = s.toInt
def function3(s: String) = s + " bar"

We'd write:

val list = function1 _ :: function2 _ :: function3 _ :: HNil

Since :: is like the cons operator that you'll find in the Scala standard library (and other languages) in that it takes its first argument (an item) and prepends it to its second (a list).

Now for your first question. Given the HList I just defined, we could write the following:

val obj = "13"

object mapFunc extends Poly1 {
  implicit def funcTo[T] = at[String => T](f => f(obj))
}

And then:

scala> (list map mapFunc) == "foo 13" :: 13 :: "13 bar" :: HNil
res0: Boolean = true

The key is that you need to represent the fact that the case applies when the map element is a function from a string (or whatever your object type is) to something.

Travis Brown
  • 138,631
  • 12
  • 375
  • 680
  • oh sry, really `HNil`, i made a mistake in writing a question, fixed, thx! – DaunnC Oct 13 '13 at 16:16
  • Hm, yes, I see, it's really exciting; and if i want to have many different functions, from diferent types to some other type? like ~ `def function1(s: Type1) = convertType1ToType2` ... `def functionn(s: Typen-1) = convertTypen-1ToTypen` ; i mean smth like `at[FromType => ToType]`; mb there is a way not to write all cases to apply implicit function? – DaunnC Oct 13 '13 at 16:45
  • 1
    @DaunnC if you want to apply an HList of functions to an HList of arguments then you should investigate zipApply ... but that's a different question. – Miles Sabin Oct 13 '13 at 17:30
  • hm, the aim is not to apply exactly, but to leave functions as they r (with thier types and possibility to apply) after using map. So for exmpl i got some other object; and i want to pass functions inside it: `implicit def funcTo[T] = at[T](t => someObject.hlist = t :: someObject.hlist)` and after applying this map function, we'll get `someObject` with HList inside: `someObject.hlist`; but, if we do as i wrote above, we cant apply functions from this new HList: `someObject.hlist.head(object)` will give us `Application doesnt take parameters` error. – DaunnC Oct 13 '13 at 17:43
  • I don't understand why the omission of parenthesis around function parameter(s) matters when creating an HList of functions; maybe there is a helpful reference if we are getting too far afield? – bbarker Aug 25 '16 at 15:54
  • Don't know if it's possible in scala but in haskell you can make type aligned BinaryTree https://hackage.haskell.org/package/type-aligned-0.9.6/docs/src/Data-TASequence-BinaryTree.html#BinaryTree And it could store sequence of functions such that input of nth function is output of n-1th function, so you have functions like this [a -> b, b ->, c -> d] and type of the tree is BinaryTree (->) a d – Safareli Dec 22 '16 at 08:53